mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 11:08:31 -05:00
Merge from master
This commit is contained in:
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { originalFSPath } from 'vs/workbench/api/node/extHost.api.impl';
|
||||
|
||||
suite('ExtHost API', function () {
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { setUnexpectedErrorHandler, errorHandler } from 'vs/base/common/errors';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { TextModel as EditorModel } from 'vs/editor/common/model/textModel';
|
||||
import { TestRPCProtocol } from './testRPCProtocol';
|
||||
@@ -33,6 +30,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import 'vs/workbench/parts/search/electron-browser/search.contribution';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
const defaultSelector = { scheme: 'far' };
|
||||
const model: ITextModel = EditorModel.createFromString(
|
||||
@@ -52,6 +50,10 @@ let commands: ExtHostCommands;
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
let originalErrorHandler: (e: any) => any;
|
||||
|
||||
function assertRejects(fn: () => Thenable<any>, message: string = 'Expected rejection') {
|
||||
return fn().then(() => assert.ok(false, message), _err => assert.ok(true));
|
||||
}
|
||||
|
||||
suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
suiteSetup(() => {
|
||||
@@ -75,10 +77,10 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
_serviceBrand: undefined,
|
||||
executeCommand(id: string, args: any): any {
|
||||
if (!CommandsRegistry.getCommands()[id]) {
|
||||
return TPromise.wrapError(new Error(id + ' NOT known'));
|
||||
return Promise.reject(new Error(id + ' NOT known'));
|
||||
}
|
||||
let { handler } = CommandsRegistry.getCommands()[id];
|
||||
return TPromise.as(instantiationService.invokeFunction(handler, args));
|
||||
return Promise.resolve(instantiationService.invokeFunction(handler, args));
|
||||
}
|
||||
});
|
||||
instantiationService.stub(IMarkerService, new MarkerService());
|
||||
@@ -147,20 +149,17 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('WorkspaceSymbols, invalid arguments', function () {
|
||||
let promises = [
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider'),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', null),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', undefined),
|
||||
commands.executeCommand('vscode.executeWorkspaceSymbolProvider', true)
|
||||
assertRejects(() => commands.executeCommand('vscode.executeWorkspaceSymbolProvider')),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeWorkspaceSymbolProvider', null)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeWorkspaceSymbolProvider', undefined)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeWorkspaceSymbolProvider', true))
|
||||
];
|
||||
|
||||
return TPromise.join(<any[]>promises).then(undefined, (err: any[]) => {
|
||||
assert.equal(err.length, 4);
|
||||
});
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
test('WorkspaceSymbols, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(nullExtensionDescription, <vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first')),
|
||||
@@ -169,7 +168,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(nullExtensionDescription, <vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(query): any {
|
||||
return [
|
||||
new types.SymbolInformation(query, types.SymbolKind.Array, new types.Range(0, 0, 1, 1), URI.parse('far://testing/first'))
|
||||
@@ -192,7 +191,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('executeWorkspaceSymbolProvider should accept empty string, #39522', async function () {
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider({
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(nullExtensionDescription, {
|
||||
provideWorkspaceSymbols(query) {
|
||||
return [new types.SymbolInformation('hello', types.SymbolKind.Array, new types.Range(0, 0, 0, 0), URI.parse('foo:bar'))];
|
||||
}
|
||||
@@ -211,25 +210,23 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('Definition, invalid arguments', function () {
|
||||
let promises = [
|
||||
commands.executeCommand('vscode.executeDefinitionProvider'),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', null),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', undefined),
|
||||
commands.executeCommand('vscode.executeDefinitionProvider', true, false)
|
||||
assertRejects(() => commands.executeCommand('vscode.executeDefinitionProvider')),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeDefinitionProvider', null)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeDefinitionProvider', undefined)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeDefinitionProvider', true, false))
|
||||
];
|
||||
|
||||
return TPromise.join(<any[]>promises).then(undefined, (err: any[]) => {
|
||||
assert.equal(err.length, 4);
|
||||
});
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
test('Definition, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(doc: any): any {
|
||||
return [
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
@@ -250,29 +247,57 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
});
|
||||
|
||||
// --- declaration
|
||||
|
||||
test('Declaration, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerDeclarationProvider(nullExtensionDescription, defaultSelector, <vscode.DeclarationProvider>{
|
||||
provideDeclaration(doc: any): any {
|
||||
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDeclarationProvider(nullExtensionDescription, defaultSelector, <vscode.DeclarationProvider>{
|
||||
provideDeclaration(doc: any): any {
|
||||
return [
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return commands.executeCommand<vscode.Location[]>('vscode.executeDeclarationProvider', model.uri, new types.Position(0, 0)).then(values => {
|
||||
assert.equal(values.length, 4);
|
||||
for (let v of values) {
|
||||
assert.ok(v.uri instanceof URI);
|
||||
assert.ok(v.range instanceof types.Range);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- type definition
|
||||
|
||||
test('Type Definition, invalid arguments', function () {
|
||||
const promises = [
|
||||
commands.executeCommand('vscode.executeTypeDefinitionProvider'),
|
||||
commands.executeCommand('vscode.executeTypeDefinitionProvider', null),
|
||||
commands.executeCommand('vscode.executeTypeDefinitionProvider', undefined),
|
||||
commands.executeCommand('vscode.executeTypeDefinitionProvider', true, false)
|
||||
assertRejects(() => commands.executeCommand('vscode.executeTypeDefinitionProvider')),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeTypeDefinitionProvider', null)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeTypeDefinitionProvider', undefined)),
|
||||
assertRejects(() => commands.executeCommand('vscode.executeTypeDefinitionProvider', true, false))
|
||||
];
|
||||
|
||||
return TPromise.join(<any[]>promises).then(undefined, (err: any[]) => {
|
||||
assert.equal(err.length, 4);
|
||||
});
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
test('Type Definition, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
provideTypeDefinition(doc: any): any {
|
||||
return new types.Location(doc.uri, new types.Range(0, 0, 0, 0));
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(nullExtensionDescription, defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
provideTypeDefinition(doc: any): any {
|
||||
return [
|
||||
new types.Location(doc.uri, new types.Range(0, 0, 0, 0)),
|
||||
@@ -297,7 +322,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('reference search, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(nullExtensionDescription, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(doc: any) {
|
||||
return [
|
||||
new types.Location(URI.parse('some:uri/path'), new types.Range(0, 1, 0, 5))
|
||||
@@ -319,7 +344,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
// --- outline
|
||||
|
||||
test('Outline, back and forth', function () {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [
|
||||
new types.SymbolInformation('testing1', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0)),
|
||||
@@ -340,10 +365,40 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
});
|
||||
|
||||
test('vscode.executeDocumentSymbolProvider command only returns SymbolInformation[] rather than DocumentSymbol[] #57984', function () {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [
|
||||
new types.SymbolInformation('SymbolInformation', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0))
|
||||
];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
let root = new types.DocumentSymbol('DocumentSymbol', 'DocumentSymbol#detail', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0), new types.Range(1, 0, 1, 0));
|
||||
root.children = [new types.DocumentSymbol('DocumentSymbol#child', 'DocumentSymbol#detail#child', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0), new types.Range(1, 0, 1, 0))];
|
||||
return [root];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return commands.executeCommand<(vscode.SymbolInformation & vscode.DocumentSymbol)[]>('vscode.executeDocumentSymbolProvider', model.uri).then(values => {
|
||||
assert.equal(values.length, 2);
|
||||
let [first, second] = values;
|
||||
assert.ok(first instanceof types.SymbolInformation);
|
||||
assert.ok(!(first instanceof types.DocumentSymbol));
|
||||
assert.ok(second instanceof types.SymbolInformation);
|
||||
assert.equal(first.name, 'DocumentSymbol');
|
||||
assert.equal(first.children.length, 1);
|
||||
assert.equal(second.name, 'SymbolInformation');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- suggest
|
||||
|
||||
test('Suggest, back and forth', function () {
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(doc, pos): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
let b = new types.CompletionItem('item2');
|
||||
@@ -401,7 +456,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
|
||||
test('Suggest, return CompletionList !array', function () {
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
let b = new types.CompletionItem('item2');
|
||||
@@ -421,7 +476,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
let resolveCount = 0;
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
let b = new types.CompletionItem('item2');
|
||||
@@ -451,7 +506,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
|
||||
test('"vscode.executeCompletionItemProvider" doesnot return a preselect field #53749', async function () {
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
a.preselect = true;
|
||||
@@ -482,10 +537,37 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
assert.equal(d.preselect, undefined);
|
||||
});
|
||||
|
||||
test('executeCompletionItemProvider doesn\'t capture commitCharacters #58228', async function () {
|
||||
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
let a = new types.CompletionItem('item1');
|
||||
a.commitCharacters = ['a', 'b'];
|
||||
let b = new types.CompletionItem('item2');
|
||||
return new types.CompletionList([a, b], false);
|
||||
}
|
||||
}, []));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
|
||||
let list = await commands.executeCommand<vscode.CompletionList>(
|
||||
'vscode.executeCompletionItemProvider',
|
||||
model.uri,
|
||||
new types.Position(0, 4),
|
||||
undefined
|
||||
);
|
||||
|
||||
assert.ok(list instanceof types.CompletionList);
|
||||
assert.equal(list.items.length, 2);
|
||||
|
||||
let [a, b] = list.items;
|
||||
assert.deepEqual(a.commitCharacters, ['a', 'b']);
|
||||
assert.equal(b.commitCharacters, undefined);
|
||||
});
|
||||
|
||||
// --- quickfix
|
||||
|
||||
test('QuickFix, back and forth', function () {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
|
||||
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
|
||||
provideCodeActions(): vscode.Command[] {
|
||||
return [{ command: 'testing', title: 'Title', arguments: [1, 2, true] }];
|
||||
}
|
||||
@@ -503,7 +585,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
|
||||
test('vscode.executeCodeActionProvider results seem to be missing their `command` property #45124', function () {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
|
||||
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
|
||||
provideCodeActions(document, range): vscode.CodeAction[] {
|
||||
return [{
|
||||
command: {
|
||||
@@ -541,7 +623,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
big: extHost
|
||||
};
|
||||
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(nullExtensionDescription, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
return [new types.CodeLens(new types.Range(0, 0, 1, 1), { title: 'Title', command: 'cmd', arguments: [1, true, complexArg] })];
|
||||
}
|
||||
@@ -565,7 +647,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
let resolveCount = 0;
|
||||
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(nullExtensionDescription, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
return [
|
||||
new types.CodeLens(new types.Range(0, 0, 1, 1)),
|
||||
@@ -597,7 +679,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('Links, back and forth', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
disposables.push(extHost.registerDocumentLinkProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
provideDocumentLinks(): any {
|
||||
return [new types.DocumentLink(new types.Range(0, 0, 0, 20), URI.parse('foo:bar'))];
|
||||
}
|
||||
@@ -620,7 +702,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('Color provider', function () {
|
||||
|
||||
disposables.push(extHost.registerColorProvider(defaultSelector, <vscode.DocumentColorProvider>{
|
||||
disposables.push(extHost.registerColorProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentColorProvider>{
|
||||
provideDocumentColors(): vscode.ColorInformation[] {
|
||||
return [new types.ColorInformation(new types.Range(0, 0, 0, 20), new types.Color(0.1, 0.2, 0.3, 0.4))];
|
||||
},
|
||||
@@ -670,7 +752,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
|
||||
test('"TypeError: e.onCancellationRequested is not a function" calling hover provider in Insiders #54174', function () {
|
||||
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(nullExtensionDescription, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('fofofofo');
|
||||
}
|
||||
@@ -683,4 +765,20 @@ suite('ExtHostLanguageFeatureCommands', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- selection ranges
|
||||
|
||||
test('Links, back and forth', async function () {
|
||||
|
||||
disposables.push(extHost.registerSelectionRangeProvider(nullExtensionDescription, defaultSelector, <vscode.SelectionRangeProvider>{
|
||||
provideSelectionRanges() {
|
||||
return [new types.Range(0, 10, 0, 18), new types.Range(0, 2, 0, 20)];
|
||||
}
|
||||
}));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
let value = await commands.executeCommand<vscode.DocumentLink[]>('vscode.executeSelectionRangeProvider', model.uri, new types.Position(0, 10));
|
||||
assert.ok(value.length >= 2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { MainThreadCommandsShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { TestRPCProtocol } from './testRPCProtocol';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
@@ -18,14 +15,15 @@ import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { Counter } from 'vs/base/common/numbers';
|
||||
|
||||
suite('ExtHostConfiguration', function () {
|
||||
|
||||
class RecordingShape extends mock<MainThreadConfigurationShape>() {
|
||||
lastArgs: [ConfigurationTarget, string, any];
|
||||
$updateConfigurationOption(target: ConfigurationTarget, key: string, value: any): TPromise<void> {
|
||||
$updateConfigurationOption(target: ConfigurationTarget, key: string, value: any): Promise<void> {
|
||||
this.lastArgs = [target, key, value];
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +31,7 @@ suite('ExtHostConfiguration', function () {
|
||||
if (!shape) {
|
||||
shape = new class extends mock<MainThreadConfigurationShape>() { };
|
||||
}
|
||||
return new ExtHostConfiguration(shape, new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()), createConfigurationData(contents));
|
||||
return new ExtHostConfiguration(shape, new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()), createConfigurationData(contents));
|
||||
}
|
||||
|
||||
function createConfigurationData(contents: any): IConfigurationInitData {
|
||||
@@ -64,7 +62,7 @@ suite('ExtHostConfiguration', function () {
|
||||
assert.equal(extHostConfig.getConfiguration('search').has('exclude.**/node_modules'), true);
|
||||
});
|
||||
|
||||
test('has/get', function () {
|
||||
test('has/get', () => {
|
||||
|
||||
const all = createExtHostConfiguration({
|
||||
'farboo': {
|
||||
@@ -267,7 +265,7 @@ suite('ExtHostConfiguration', function () {
|
||||
test('inspect in no workspace context', function () {
|
||||
const testObject = new ExtHostConfiguration(
|
||||
new class extends mock<MainThreadConfigurationShape>() { },
|
||||
new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService()),
|
||||
new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()),
|
||||
{
|
||||
defaults: new ConfigurationModel({
|
||||
'editor': {
|
||||
@@ -314,7 +312,7 @@ suite('ExtHostConfiguration', function () {
|
||||
'id': 'foo',
|
||||
'folders': [aWorkspaceFolder(URI.file('foo'), 0)],
|
||||
'name': 'foo'
|
||||
}, new NullLogService()),
|
||||
}, new NullLogService(), new Counter()),
|
||||
{
|
||||
defaults: new ConfigurationModel({
|
||||
'editor': {
|
||||
@@ -388,7 +386,7 @@ suite('ExtHostConfiguration', function () {
|
||||
'id': 'foo',
|
||||
'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)],
|
||||
'name': 'foo'
|
||||
}, new NullLogService()),
|
||||
}, new NullLogService(), new Counter()),
|
||||
{
|
||||
defaults: new ConfigurationModel({
|
||||
'editor': {
|
||||
@@ -577,8 +575,8 @@ suite('ExtHostConfiguration', function () {
|
||||
test('update/error-state not OK', function () {
|
||||
|
||||
const shape = new class extends mock<MainThreadConfigurationShape>() {
|
||||
$updateConfigurationOption(target: ConfigurationTarget, key: string, value: any): TPromise<any> {
|
||||
return TPromise.wrapError(new Error('Unknown Key')); // something !== OK
|
||||
$updateConfigurationOption(target: ConfigurationTarget, key: string, value: any): Promise<any> {
|
||||
return Promise.reject(new Error('Unknown Key')); // something !== OK
|
||||
}
|
||||
};
|
||||
|
||||
@@ -597,7 +595,7 @@ suite('ExtHostConfiguration', function () {
|
||||
'id': 'foo',
|
||||
'folders': [workspaceFolder],
|
||||
'name': 'foo'
|
||||
}, new NullLogService()),
|
||||
}, new NullLogService(), new Counter()),
|
||||
createConfigurationData({
|
||||
'farboo': {
|
||||
'config': false,
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { DiagnosticCollection, ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { Diagnostic, DiagnosticSeverity, Range, DiagnosticRelatedInformation, Location } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { MainThreadDiagnosticsShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
@@ -25,7 +23,7 @@ suite('ExtHostDiagnostics', () => {
|
||||
}
|
||||
}
|
||||
|
||||
test('disposeCheck', function () {
|
||||
test('disposeCheck', () => {
|
||||
|
||||
const collection = new DiagnosticCollection('test', 'test', 100, new DiagnosticsShape(), new Emitter());
|
||||
|
||||
@@ -190,6 +188,31 @@ suite('ExtHostDiagnostics', () => {
|
||||
lastEntries = undefined;
|
||||
});
|
||||
|
||||
test('don\'t send message when not making a change', function () {
|
||||
|
||||
let changeCount = 0;
|
||||
let eventCount = 0;
|
||||
|
||||
const emitter = new Emitter<any>();
|
||||
emitter.event(_ => eventCount += 1);
|
||||
const collection = new DiagnosticCollection('test', 'test', 100, new class extends DiagnosticsShape {
|
||||
$changeMany() {
|
||||
changeCount += 1;
|
||||
}
|
||||
}, emitter);
|
||||
|
||||
let uri = URI.parse('sc:hightower');
|
||||
let diag = new Diagnostic(new Range(0, 0, 0, 1), 'ffff');
|
||||
|
||||
collection.set(uri, [diag]);
|
||||
assert.equal(changeCount, 1);
|
||||
assert.equal(eventCount, 1);
|
||||
|
||||
collection.set(uri, [diag]);
|
||||
assert.equal(changeCount, 1);
|
||||
assert.equal(eventCount, 2);
|
||||
});
|
||||
|
||||
test('diagnostics collection, tuples and undefined (small array), #15585', function () {
|
||||
|
||||
const collection = new DiagnosticCollection('test', 'test', 100, new DiagnosticsShape(), new Emitter());
|
||||
@@ -376,4 +399,29 @@ suite('ExtHostDiagnostics', () => {
|
||||
assert.equal(ownerHistory[0], 'foo');
|
||||
assert.equal(ownerHistory[1], 'foo0');
|
||||
});
|
||||
|
||||
test('Error updating diagnostics from extension #60394', function () {
|
||||
let callCount = 0;
|
||||
let collection = new DiagnosticCollection('ddd', 'test', 100, new class extends DiagnosticsShape {
|
||||
$changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]) {
|
||||
callCount += 1;
|
||||
}
|
||||
}, new Emitter<any>());
|
||||
|
||||
let array: Diagnostic[] = [];
|
||||
let diag1 = new Diagnostic(new Range(0, 0, 1, 1), 'Foo');
|
||||
let diag2 = new Diagnostic(new Range(0, 0, 1, 1), 'Bar');
|
||||
|
||||
array.push(diag1, diag2);
|
||||
|
||||
collection.set(URI.parse('test:me'), array);
|
||||
assert.equal(callCount, 1);
|
||||
|
||||
collection.set(URI.parse('test:me'), array);
|
||||
assert.equal(callCount, 1); // equal array
|
||||
|
||||
array.push(diag2);
|
||||
collection.set(URI.parse('test:me'), array);
|
||||
assert.equal(callCount, 2); // same but un-equal array
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/node/extHostDocumentData';
|
||||
import { Position } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { MainThreadDocumentsShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
|
||||
@@ -41,7 +38,7 @@ suite('ExtHostDocumentData', () => {
|
||||
], '\n', 'text', 1, false);
|
||||
});
|
||||
|
||||
test('readonly-ness', function () {
|
||||
test('readonly-ness', () => {
|
||||
assert.throws((): void => (data as any).document.uri = null);
|
||||
assert.throws(() => (data as any).document.fileName = 'foofile');
|
||||
assert.throws(() => (data as any).document.isDirty = false);
|
||||
@@ -56,7 +53,7 @@ suite('ExtHostDocumentData', () => {
|
||||
$trySaveDocument(uri: URI) {
|
||||
assert.ok(!saved);
|
||||
saved = uri;
|
||||
return TPromise.as(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}, URI.parse('foo:bar'), [], '\n', 'text', 1, true);
|
||||
|
||||
@@ -81,7 +78,7 @@ suite('ExtHostDocumentData', () => {
|
||||
assert.equal(document.lineAt(0).text, 'This is line one');
|
||||
});
|
||||
|
||||
test('lines', function () {
|
||||
test('lines', () => {
|
||||
|
||||
assert.equal(data.document.lineCount, 4);
|
||||
|
||||
@@ -138,7 +135,7 @@ suite('ExtHostDocumentData', () => {
|
||||
|
||||
});
|
||||
|
||||
test('offsetAt', function () {
|
||||
test('offsetAt', () => {
|
||||
assertOffsetAt(0, 0, 0);
|
||||
assertOffsetAt(0, 1, 1);
|
||||
assertOffsetAt(0, 16, 16);
|
||||
@@ -228,7 +225,7 @@ suite('ExtHostDocumentData', () => {
|
||||
assertOffsetAt(1, 0, 25);
|
||||
});
|
||||
|
||||
test('positionAt', function () {
|
||||
test('positionAt', () => {
|
||||
assertPositionAt(0, 0, 0);
|
||||
assertPositionAt(Number.MIN_VALUE, 0, 0);
|
||||
assertPositionAt(1, 0, 1);
|
||||
@@ -242,7 +239,7 @@ suite('ExtHostDocumentData', () => {
|
||||
assertPositionAt(Number.MAX_VALUE, 3, 29);
|
||||
});
|
||||
|
||||
test('getWordRangeAtPosition', function () {
|
||||
test('getWordRangeAtPosition', () => {
|
||||
data = new ExtHostDocumentData(undefined, URI.file(''), [
|
||||
'aaaa bbbb+cccc abc'
|
||||
], '\n', 'text', 1, false);
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbench/api/node/extHostTypes';
|
||||
@@ -211,7 +208,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
|
||||
let sub = participant.getOnWillSaveTextDocumentEvent(nullExtensionDescription)(function (event) {
|
||||
|
||||
event.waitUntil(new TPromise((resolve, reject) => {
|
||||
event.waitUntil(new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
assert.throws(() => event.waitUntil(timeout(10)));
|
||||
@@ -248,7 +245,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, mainThreadEditors);
|
||||
|
||||
let sub1 = participant.getOnWillSaveTextDocumentEvent(nullExtensionDescription)(function (e) {
|
||||
e.waitUntil(TPromise.wrapError(new Error('dddd')));
|
||||
e.waitUntil(Promise.reject(new Error('dddd')));
|
||||
});
|
||||
|
||||
let event: vscode.TextDocumentWillSaveEvent;
|
||||
@@ -269,13 +266,13 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, new class extends mock<MainThreadTextEditorsShape>() {
|
||||
$tryApplyWorkspaceEdit(_edits: WorkspaceEditDto) {
|
||||
dto = _edits;
|
||||
return TPromise.as(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
let sub = participant.getOnWillSaveTextDocumentEvent(nullExtensionDescription)(function (e) {
|
||||
e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
e.waitUntil(TPromise.as([TextEdit.setEndOfLine(EndOfLine.CRLF)]));
|
||||
e.waitUntil(Promise.resolve([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
e.waitUntil(Promise.resolve([TextEdit.setEndOfLine(EndOfLine.CRLF)]));
|
||||
});
|
||||
|
||||
return participant.$participateInSave(resource, SaveReason.EXPLICIT).then(() => {
|
||||
@@ -293,7 +290,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, new class extends mock<MainThreadTextEditorsShape>() {
|
||||
$tryApplyWorkspaceEdit(_edits: WorkspaceEditDto) {
|
||||
edits = _edits;
|
||||
return TPromise.as(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -311,7 +308,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
versionId: 2
|
||||
}, true);
|
||||
|
||||
e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
e.waitUntil(Promise.resolve([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
});
|
||||
|
||||
return participant.$participateInSave(resource, SaveReason.EXPLICIT).then(values => {
|
||||
@@ -348,7 +345,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.as(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -359,7 +356,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
assert.equal(document.version, 1);
|
||||
assert.equal(document.getText(), 'foo');
|
||||
|
||||
e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
e.waitUntil(Promise.resolve([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
});
|
||||
|
||||
let sub2 = participant.getOnWillSaveTextDocumentEvent(nullExtensionDescription)(function (e) {
|
||||
@@ -367,7 +364,7 @@ suite('ExtHostDocumentSaveParticipant', () => {
|
||||
assert.equal(document.version, 2);
|
||||
assert.equal(document.getText(), 'barfoo');
|
||||
|
||||
e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
e.waitUntil(Promise.resolve([TextEdit.insert(new Position(0, 0), 'bar')]));
|
||||
});
|
||||
|
||||
return participant.$participateInSave(resource, SaveReason.EXPLICIT).then(values => {
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
|
||||
suite('ExtHostDocumentsAndEditors', () => {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ExtHostFileSystemEventService } from 'vs/workbench/api/node/extHostFileSystemEventService';
|
||||
import { IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { setUnexpectedErrorHandler, errorHandler } from 'vs/base/common/errors';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { TextModel as EditorModel } from 'vs/editor/common/model/textModel';
|
||||
import { Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { Position as EditorPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { TestRPCProtocol } from './testRPCProtocol';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
@@ -24,9 +22,9 @@ import { IHeapService } from 'vs/workbench/api/electron-browser/mainThreadHeapSe
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/quickOpen';
|
||||
import { DocumentSymbolProviderRegistry, DocumentHighlightKind, Hover, ResourceTextEdit } from 'vs/editor/common/modes';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { getCodeLensData } from 'vs/editor/contrib/codelens/codelens';
|
||||
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDefinition/goToDefinition';
|
||||
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition } from 'vs/editor/contrib/goToDefinition/goToDefinition';
|
||||
import { getHover } from 'vs/editor/contrib/hover/getHover';
|
||||
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/wordHighlighter';
|
||||
import { provideReferences } from 'vs/editor/contrib/referenceSearch/referenceSearch';
|
||||
@@ -37,7 +35,6 @@ import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/provideSi
|
||||
import { provideSuggestionItems } from 'vs/editor/contrib/suggest/suggest';
|
||||
import { getDocumentFormattingEdits, getDocumentRangeFormattingEdits, getOnTypeFormattingEdits } from 'vs/editor/contrib/format/format';
|
||||
import { getLinks } from 'vs/editor/contrib/links/getLinks';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { MainContext, ExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
|
||||
@@ -47,6 +44,8 @@ import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { ITextModel, EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import { getColors } from 'vs/editor/contrib/colorPicker/color';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { nullExtensionDescription as defaultExtension } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/smartSelect';
|
||||
|
||||
const defaultSelector = { scheme: 'far' };
|
||||
const model: ITextModel = EditorModel.createFromString(
|
||||
@@ -134,15 +133,15 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
// --- outline
|
||||
|
||||
test('DocumentSymbols, register/deregister', function () {
|
||||
assert.equal(DocumentSymbolProviderRegistry.all(model).length, 0);
|
||||
let d1 = extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
assert.equal(modes.DocumentSymbolProviderRegistry.all(model).length, 0);
|
||||
let d1 = extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols() {
|
||||
return <vscode.SymbolInformation[]>[];
|
||||
}
|
||||
});
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
assert.equal(DocumentSymbolProviderRegistry.all(model).length, 1);
|
||||
assert.equal(modes.DocumentSymbolProviderRegistry.all(model).length, 1);
|
||||
d1.dispose();
|
||||
return rpcProtocol.sync();
|
||||
});
|
||||
@@ -150,12 +149,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
});
|
||||
|
||||
test('DocumentSymbols, evil provider', function () {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
throw new Error('evil document symbol provider');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -163,14 +162,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDocumentSymbols(model).then(value => {
|
||||
return getDocumentSymbols(model, true, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('DocumentSymbols, data conversion', function () {
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
disposables.push(extHost.registerDocumentSymbolProvider(defaultExtension, defaultSelector, <vscode.DocumentSymbolProvider>{
|
||||
provideDocumentSymbols(): any {
|
||||
return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -178,7 +177,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDocumentSymbols(model).then(value => {
|
||||
return getDocumentSymbols(model, true, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
|
||||
let entry = value[0];
|
||||
@@ -192,12 +191,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('CodeLens, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses() {
|
||||
return [new types.CodeLens(new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -212,7 +211,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('CodeLens, do not resolve a resolved lens', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses(): any {
|
||||
return [new types.CodeLens(
|
||||
new types.Range(0, 0, 0, 0),
|
||||
@@ -228,10 +227,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
return getCodeLensData(model, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let data = value[0];
|
||||
|
||||
return asWinJsPromise((token) => {
|
||||
return data.provider.resolveCodeLens(model, data.symbol, token);
|
||||
}).then(symbol => {
|
||||
return Promise.resolve(data.provider.resolveCodeLens(model, data.symbol, CancellationToken.None)).then(symbol => {
|
||||
assert.equal(symbol.command.id, 'id');
|
||||
assert.equal(symbol.command.title, 'Title');
|
||||
});
|
||||
@@ -241,7 +237,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('CodeLens, missing command', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
|
||||
disposables.push(extHost.registerCodeLensProvider(defaultExtension, defaultSelector, <vscode.CodeLensProvider>{
|
||||
provideCodeLenses() {
|
||||
return [new types.CodeLens(new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -253,9 +249,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
assert.equal(value.length, 1);
|
||||
|
||||
let data = value[0];
|
||||
return asWinJsPromise((token) => {
|
||||
return data.provider.resolveCodeLens(model, data.symbol, token);
|
||||
}).then(symbol => {
|
||||
return Promise.resolve(data.provider.resolveCodeLens(model, data.symbol, CancellationToken.None)).then(symbol => {
|
||||
|
||||
assert.equal(symbol.command.id, 'missing');
|
||||
assert.equal(symbol.command.title, '<<MISSING COMMAND>>');
|
||||
@@ -268,7 +262,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Definition, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||
}
|
||||
@@ -276,7 +270,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
@@ -287,12 +281,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Definition, one or many', function () {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 1, 1, 1))];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return new types.Location(model.uri, new types.Range(1, 1, 1, 1));
|
||||
}
|
||||
@@ -300,7 +294,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
});
|
||||
});
|
||||
@@ -308,13 +302,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Definition, registration order', function () {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return [new types.Location(URI.parse('far://first'), new types.Range(2, 3, 4, 5))];
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return new types.Location(URI.parse('far://second'), new types.Range(1, 2, 3, 4));
|
||||
}
|
||||
@@ -322,7 +316,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
// let [first, second] = value;
|
||||
|
||||
@@ -334,12 +328,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Definition, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
throw new Error('evil provider');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
|
||||
disposables.push(extHost.registerDefinitionProvider(defaultExtension, defaultSelector, <vscode.DefinitionProvider>{
|
||||
provideDefinition(): any {
|
||||
return new types.Location(model.uri, new types.Range(1, 1, 1, 1));
|
||||
}
|
||||
@@ -347,24 +341,45 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// -- declaration
|
||||
|
||||
test('Declaration, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerDeclarationProvider(defaultExtension, defaultSelector, <vscode.DeclarationProvider>{
|
||||
provideDeclaration(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return getDeclarationsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
assert.equal(entry.uri.toString(), model.uri.toString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- implementation
|
||||
|
||||
test('Implementation, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerImplementationProvider(defaultSelector, <vscode.ImplementationProvider>{
|
||||
disposables.push(extHost.registerImplementationProvider(defaultExtension, defaultSelector, <vscode.ImplementationProvider>{
|
||||
provideImplementation(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getImplementationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getImplementationsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
@@ -377,14 +392,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Type Definition, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(defaultExtension, defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
provideTypeDefinition(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getTypeDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getTypeDefinitionsAtPosition(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
@@ -397,7 +412,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('HoverProvider, word range at pos', function () {
|
||||
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('Hello');
|
||||
}
|
||||
@@ -415,7 +430,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('HoverProvider, given range', function () {
|
||||
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('Hello', new types.Range(3, 0, 8, 7));
|
||||
}
|
||||
@@ -433,14 +448,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
|
||||
test('HoverProvider, registration order', function () {
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('registered first');
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('registered second');
|
||||
}
|
||||
@@ -449,7 +464,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getHover(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
let [first, second] = value as Hover[];
|
||||
let [first, second] = value as modes.Hover[];
|
||||
assert.equal(first.contents[0].value, 'registered second');
|
||||
assert.equal(second.contents[0].value, 'registered first');
|
||||
});
|
||||
@@ -459,12 +474,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('HoverProvider, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
|
||||
disposables.push(extHost.registerHoverProvider(defaultExtension, defaultSelector, <vscode.HoverProvider>{
|
||||
provideHover(): any {
|
||||
return new types.Hover('Hello');
|
||||
}
|
||||
@@ -483,7 +498,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Occurrences, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
|
||||
}
|
||||
@@ -495,19 +510,19 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 });
|
||||
assert.equal(entry.kind, DocumentHighlightKind.Text);
|
||||
assert.equal(entry.kind, modes.DocumentHighlightKind.Text);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Occurrences, order 1/2', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentHighlightProvider('*', <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, '*', <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
|
||||
}
|
||||
@@ -519,19 +534,19 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 });
|
||||
assert.equal(entry.kind, DocumentHighlightKind.Text);
|
||||
assert.equal(entry.kind, modes.DocumentHighlightKind.Text);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Occurrences, order 2/2', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [new types.DocumentHighlight(new types.Range(0, 0, 0, 2))];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentHighlightProvider('*', <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, '*', <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
|
||||
}
|
||||
@@ -543,20 +558,20 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 3 });
|
||||
assert.equal(entry.kind, DocumentHighlightKind.Text);
|
||||
assert.equal(entry.kind, modes.DocumentHighlightKind.Text);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Occurrences, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
disposables.push(extHost.registerDocumentHighlightProvider(defaultExtension, defaultSelector, <vscode.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights(): any {
|
||||
return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
|
||||
}
|
||||
@@ -574,13 +589,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('References, registration order', function () {
|
||||
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(): any {
|
||||
return [new types.Location(URI.parse('far://register/first'), new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(): any {
|
||||
return [new types.Location(URI.parse('far://register/second'), new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -600,7 +615,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('References, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(): any {
|
||||
return [new types.Location(model.uri, new types.Position(0, 0))];
|
||||
}
|
||||
@@ -621,12 +636,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('References, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
|
||||
disposables.push(extHost.registerReferenceProvider(defaultExtension, defaultSelector, <vscode.ReferenceProvider>{
|
||||
provideReferences(): any {
|
||||
return [new types.Location(model.uri, new types.Range(0, 0, 0, 0))];
|
||||
}
|
||||
@@ -645,7 +660,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Quick Fix, command data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, {
|
||||
provideCodeActions(): vscode.Command[] {
|
||||
return [
|
||||
{ command: 'test1', title: 'Testing1' },
|
||||
@@ -669,7 +684,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Quick Fix, code action data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, {
|
||||
provideCodeActions(): vscode.CodeAction[] {
|
||||
return [
|
||||
{
|
||||
@@ -697,7 +712,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Cannot read property \'id\' of undefined, #29469', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, <vscode.CodeActionProvider>{
|
||||
provideCodeActions(): any {
|
||||
return [
|
||||
undefined,
|
||||
@@ -716,12 +731,12 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Quick Fix, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, <vscode.CodeActionProvider>{
|
||||
provideCodeActions(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
|
||||
disposables.push(extHost.registerCodeActionProvider(defaultExtension, defaultSelector, <vscode.CodeActionProvider>{
|
||||
provideCodeActions(): any {
|
||||
return [<vscode.Command>{ command: 'test', title: 'Testing' }];
|
||||
}
|
||||
@@ -738,13 +753,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Navigate types, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, <vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
|
||||
disposables.push(extHost.registerWorkspaceSymbolProvider(defaultExtension, <vscode.WorkspaceSymbolProvider>{
|
||||
provideWorkspaceSymbols(): any {
|
||||
return [new types.SymbolInformation('testing', types.SymbolKind.Array, new types.Range(0, 0, 1, 1))];
|
||||
}
|
||||
@@ -766,7 +781,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Rename, evil provider 0/2', function () {
|
||||
|
||||
disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
throw new class Foo { };
|
||||
}
|
||||
@@ -784,7 +799,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Rename, evil provider 1/2', function () {
|
||||
|
||||
disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
throw Error('evil');
|
||||
}
|
||||
@@ -800,13 +815,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Rename, evil provider 2/2', function () {
|
||||
|
||||
disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, '*', <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
throw Error('evil');
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
let edit = new types.WorkspaceEdit();
|
||||
edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
|
||||
@@ -824,7 +839,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Rename, ordering', function () {
|
||||
|
||||
disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, '*', <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
let edit = new types.WorkspaceEdit();
|
||||
edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
|
||||
@@ -833,7 +848,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
|
||||
disposables.push(extHost.registerRenameProvider(defaultExtension, defaultSelector, <vscode.RenameProvider>{
|
||||
provideRenameEdits(): any {
|
||||
return;
|
||||
}
|
||||
@@ -844,8 +859,8 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
|
||||
// least relevant rename provider
|
||||
assert.equal(value.edits.length, 2);
|
||||
assert.equal((<ResourceTextEdit>value.edits[0]).edits.length, 1);
|
||||
assert.equal((<ResourceTextEdit>value.edits[1]).edits.length, 1);
|
||||
assert.equal((<modes.ResourceTextEdit>value.edits[0]).edits.length, 1);
|
||||
assert.equal((<modes.ResourceTextEdit>value.edits[1]).edits.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -854,13 +869,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Parameter Hints, order', function () {
|
||||
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
provideSignatureHelp(): any {
|
||||
return undefined;
|
||||
}
|
||||
}, []));
|
||||
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
provideSignatureHelp(): vscode.SignatureHelp {
|
||||
return {
|
||||
signatures: [],
|
||||
@@ -872,14 +887,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return provideSignatureHelp(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
return provideSignatureHelp(model, new EditorPosition(1, 1), { triggerKind: modes.SignatureHelpTriggerKind.Invoke, isRetrigger: false }, CancellationToken.None).then(value => {
|
||||
assert.ok(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
test('Parameter Hints, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
disposables.push(extHost.registerSignatureHelpProvider(defaultExtension, defaultSelector, <vscode.SignatureHelpProvider>{
|
||||
provideSignatureHelp(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
@@ -887,7 +902,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
|
||||
return provideSignatureHelp(model, new EditorPosition(1, 1), CancellationToken.None).then(value => {
|
||||
return provideSignatureHelp(model, new EditorPosition(1, 1), { triggerKind: modes.SignatureHelpTriggerKind.Invoke, isRetrigger: false }, CancellationToken.None).then(value => {
|
||||
assert.equal(value, undefined);
|
||||
});
|
||||
});
|
||||
@@ -897,13 +912,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Suggest, order 1/3', function () {
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider('*', <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, '*', <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('testing1')];
|
||||
}
|
||||
}, []));
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('testing2')];
|
||||
}
|
||||
@@ -919,13 +934,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Suggest, order 2/3', function () {
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider('*', <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, '*', <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('weak-selector')]; // weaker selector but result
|
||||
}
|
||||
}, []));
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return []; // stronger selector but not a good result;
|
||||
}
|
||||
@@ -941,13 +956,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Suggest, order 2/3', function () {
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('strong-1')];
|
||||
}
|
||||
}, []));
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('strong-2')];
|
||||
}
|
||||
@@ -964,13 +979,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Suggest, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}, []));
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return [new types.CompletionItem('testing')];
|
||||
}
|
||||
@@ -987,7 +1002,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Suggest, CompletionList', function () {
|
||||
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
|
||||
disposables.push(extHost.registerCompletionItemProvider(defaultExtension, defaultSelector, <vscode.CompletionItemProvider>{
|
||||
provideCompletionItems(): any {
|
||||
return new types.CompletionList([<any>new types.CompletionItem('hello')], true);
|
||||
}
|
||||
@@ -1004,14 +1019,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
// --- format
|
||||
|
||||
test('Format Doc, data conversion', function () {
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing'), types.TextEdit.setEndOfLine(types.EndOfLine.LF)];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
let [first, second] = value;
|
||||
assert.equal(first.text, 'testing');
|
||||
@@ -1019,45 +1034,45 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
assert.equal(second.eol, EndOfLineSequence.LF);
|
||||
assert.equal(second.text, '');
|
||||
assert.equal(second.range, undefined);
|
||||
assert.deepEqual(second.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Format Doc, evil provider', function () {
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 });
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
|
||||
});
|
||||
});
|
||||
|
||||
test('Format Doc, order', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
return undefined;
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
return undefined;
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
|
||||
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
assert.equal(first.text, 'testing');
|
||||
@@ -1067,14 +1082,14 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
});
|
||||
|
||||
test('Format Range, data conversion', function () {
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
provideDocumentRangeFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
assert.equal(first.text, 'testing');
|
||||
@@ -1084,23 +1099,23 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
});
|
||||
|
||||
test('Format Range, + format_doc', function () {
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
provideDocumentRangeFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'range')];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
provideDocumentRangeFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(2, 3, 4, 5), 'range2')];
|
||||
}
|
||||
}));
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentFormattingEditProvider>{
|
||||
provideDocumentFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 1, 1), 'doc')];
|
||||
}
|
||||
}));
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [first] = value;
|
||||
assert.equal(first.text, 'range2');
|
||||
@@ -1113,20 +1128,20 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
});
|
||||
|
||||
test('Format Range, evil provider', function () {
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultExtension, defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
|
||||
provideDocumentRangeFormattingEdits(): any {
|
||||
throw new Error('evil');
|
||||
}
|
||||
}));
|
||||
|
||||
return rpcProtocol.sync().then(() => {
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 });
|
||||
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
|
||||
});
|
||||
});
|
||||
|
||||
test('Format on Type, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerOnTypeFormattingEditProvider(defaultSelector, <vscode.OnTypeFormattingEditProvider>{
|
||||
disposables.push(extHost.registerOnTypeFormattingEditProvider(defaultExtension, defaultSelector, <vscode.OnTypeFormattingEditProvider>{
|
||||
provideOnTypeFormattingEdits(): any {
|
||||
return [new types.TextEdit(new types.Range(0, 0, 0, 0), arguments[2])];
|
||||
}
|
||||
@@ -1145,7 +1160,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Links, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
provideDocumentLinks() {
|
||||
return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
|
||||
}
|
||||
@@ -1164,13 +1179,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Links, evil provider', function () {
|
||||
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
provideDocumentLinks() {
|
||||
return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
disposables.push(extHost.registerDocumentLinkProvider(defaultExtension, defaultSelector, <vscode.DocumentLinkProvider>{
|
||||
provideDocumentLinks(): any {
|
||||
throw new Error();
|
||||
}
|
||||
@@ -1189,7 +1204,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
test('Document colors, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerColorProvider(defaultSelector, <vscode.DocumentColorProvider>{
|
||||
disposables.push(extHost.registerColorProvider(defaultExtension, defaultSelector, <vscode.DocumentColorProvider>{
|
||||
provideDocumentColors(): vscode.ColorInformation[] {
|
||||
return [new types.ColorInformation(new types.Range(0, 0, 0, 20), new types.Color(0.1, 0.2, 0.3, 0.4))];
|
||||
},
|
||||
@@ -1208,4 +1223,20 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// -- selection ranges
|
||||
|
||||
test('Selection Ranges, data conversion', async function () {
|
||||
disposables.push(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, <vscode.SelectionRangeProvider>{
|
||||
provideSelectionRanges() {
|
||||
return [new types.Range(0, 10, 0, 18), new types.Range(0, 2, 0, 20)];
|
||||
}
|
||||
}));
|
||||
|
||||
await rpcProtocol.sync();
|
||||
|
||||
provideSelectionRanges(model, new Position(1, 17), CancellationToken.None).then(ranges => {
|
||||
assert.ok(ranges.length >= 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MainThreadMessageService } from 'vs/workbench/api/electron-browser/mainThreadMessageService';
|
||||
import { TPromise as Promise, TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotificationService, INotification, NoOpNotification, INotificationHandle, Severity, IPromptChoice } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, INotification, NoOpNotification, INotificationHandle, Severity, IPromptChoice, IPromptOptions } from 'vs/platform/notification/common/notification';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
|
||||
const emptyDialogService = new class implements IDialogService {
|
||||
_serviceBrand: 'dialogService';
|
||||
@@ -26,8 +24,8 @@ const emptyDialogService = new class implements IDialogService {
|
||||
const emptyCommandService: ICommandService = {
|
||||
_serviceBrand: undefined,
|
||||
onWillExecuteCommand: () => ({ dispose: () => { } }),
|
||||
executeCommand: (commandId: string, ...args: any[]): TPromise<any> => {
|
||||
return TPromise.as(void 0);
|
||||
executeCommand: (commandId: string, ...args: any[]): Promise<any> => {
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,7 +43,7 @@ const emptyNotificationService = new class implements INotificationService {
|
||||
error(...args: any[]): never {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
prompt(severity: Severity, message: string, choices: IPromptChoice[], onCancel?: () => void): INotificationHandle {
|
||||
prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
};
|
||||
@@ -71,65 +69,61 @@ class EmptyNotificationService implements INotificationService {
|
||||
error(message: any): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
prompt(severity: Severity, message: string, choices: IPromptChoice[], onCancel?: () => void): INotificationHandle {
|
||||
prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
suite('ExtHostMessageService', function () {
|
||||
|
||||
test('propagte handle on select', function () {
|
||||
test('propagte handle on select', async function () {
|
||||
|
||||
let service = new MainThreadMessageService(null, new EmptyNotificationService(notification => {
|
||||
assert.equal(notification.actions.primary.length, 1);
|
||||
setImmediate(() => notification.actions.primary[0].run());
|
||||
}), emptyCommandService, emptyDialogService);
|
||||
|
||||
return service.$showMessage(1, 'h', {}, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]).then(handle => {
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
const handle = await service.$showMessage(1, 'h', {}, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]);
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
|
||||
suite('modal', () => {
|
||||
test('calls dialog service', () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, {
|
||||
test('calls dialog service', async () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {
|
||||
show(severity, message, buttons) {
|
||||
assert.equal(severity, 1);
|
||||
assert.equal(message, 'h');
|
||||
assert.equal(buttons.length, 2);
|
||||
assert.equal(buttons[1], 'Cancel');
|
||||
return Promise.as(0);
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
} as IDialogService);
|
||||
|
||||
return service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]).then(handle => {
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]);
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
|
||||
test('returns undefined when cancelled', () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, {
|
||||
test('returns undefined when cancelled', async () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {
|
||||
show(severity, message, buttons) {
|
||||
return Promise.as(1);
|
||||
return Promise.resolve(1);
|
||||
}
|
||||
} as IDialogService);
|
||||
|
||||
return service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]).then(handle => {
|
||||
assert.equal(handle, undefined);
|
||||
});
|
||||
const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: false }]);
|
||||
assert.equal(handle, undefined);
|
||||
});
|
||||
|
||||
test('hides Cancel button when not needed', () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, {
|
||||
test('hides Cancel button when not needed', async () => {
|
||||
const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock<IDialogService>() {
|
||||
show(severity, message, buttons) {
|
||||
assert.equal(buttons.length, 1);
|
||||
return Promise.as(0);
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
} as IDialogService);
|
||||
|
||||
return service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]).then(handle => {
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
const handle = await service.$showMessage(1, 'h', { modal: true }, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]);
|
||||
assert.equal(handle, 42);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,20 +2,22 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { mapArrayOrNot } from 'vs/base/common/arrays';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import { IFileMatch, IPatternInfo, IRawFileMatch2, IRawSearchQuery, ISearchCompleteStats, ISearchQuery, QueryType } from 'vs/platform/search/common/search';
|
||||
import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteStats, ISearchQuery, ITextQuery, QueryType, resultIsMatch } from 'vs/platform/search/common/search';
|
||||
import { MainContext, MainThreadSearchShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
|
||||
import { Range } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { extensionResultIsMatch } from 'vs/workbench/services/search/node/textSearchManager';
|
||||
import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol';
|
||||
import { TestLogService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
let rpcProtocol: TestRPCProtocol;
|
||||
@@ -58,6 +60,12 @@ class MockMainThreadSearch implements MainThreadSearchShape {
|
||||
}
|
||||
}
|
||||
|
||||
class MockExtHostConfiguration {
|
||||
getConfiguration(section?: string, resource?: URI, extensionId?: string): vscode.WorkspaceConfiguration {
|
||||
return <vscode.WorkspaceConfiguration>{};
|
||||
}
|
||||
}
|
||||
|
||||
let mockExtfs: Partial<typeof extfs>;
|
||||
|
||||
suite('ExtHostSearch', () => {
|
||||
@@ -71,13 +79,14 @@ suite('ExtHostSearch', () => {
|
||||
await rpcProtocol.sync();
|
||||
}
|
||||
|
||||
async function runFileSearch(query: IRawSearchQuery, cancel = false): Promise<{ results: URI[]; stats: ISearchCompleteStats }> {
|
||||
async function runFileSearch(query: IFileQuery, cancel = false): Promise<{ results: URI[]; stats: ISearchCompleteStats }> {
|
||||
let stats: ISearchCompleteStats;
|
||||
try {
|
||||
const p = extHostSearch.$provideFileSearchResults(mockMainThreadSearch.lastHandle, 0, query);
|
||||
const cancellation = new CancellationTokenSource();
|
||||
const p = extHostSearch.$provideFileSearchResults(mockMainThreadSearch.lastHandle, 0, query, cancellation.token);
|
||||
if (cancel) {
|
||||
await new TPromise(resolve => process.nextTick(resolve));
|
||||
p.cancel();
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
cancellation.cancel();
|
||||
}
|
||||
|
||||
stats = await p;
|
||||
@@ -95,13 +104,14 @@ suite('ExtHostSearch', () => {
|
||||
};
|
||||
}
|
||||
|
||||
async function runTextSearch(pattern: IPatternInfo, query: IRawSearchQuery, cancel = false): Promise<{ results: IFileMatch[], stats: ISearchCompleteStats }> {
|
||||
async function runTextSearch(query: ITextQuery, cancel = false): Promise<{ results: IFileMatch[], stats: ISearchCompleteStats }> {
|
||||
let stats: ISearchCompleteStats;
|
||||
try {
|
||||
const p = extHostSearch.$provideTextSearchResults(mockMainThreadSearch.lastHandle, 0, pattern, query);
|
||||
const cancellation = new CancellationTokenSource();
|
||||
const p = extHostSearch.$provideTextSearchResults(mockMainThreadSearch.lastHandle, 0, query, cancellation.token);
|
||||
if (cancel) {
|
||||
await new TPromise(resolve => process.nextTick(resolve));
|
||||
p.cancel();
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
cancellation.cancel();
|
||||
}
|
||||
|
||||
stats = await p;
|
||||
@@ -127,11 +137,13 @@ suite('ExtHostSearch', () => {
|
||||
rpcProtocol = new TestRPCProtocol();
|
||||
|
||||
mockMainThreadSearch = new MockMainThreadSearch();
|
||||
const logService = new TestLogService();
|
||||
const ehConfiguration: ExtHostConfiguration = new MockExtHostConfiguration() as any;
|
||||
|
||||
rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch);
|
||||
|
||||
mockExtfs = {};
|
||||
extHostSearch = new ExtHostSearch(rpcProtocol, null, mockExtfs as typeof extfs);
|
||||
extHostSearch = new ExtHostSearch(rpcProtocol, null, logService, ehConfiguration, mockExtfs as typeof extfs);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
@@ -146,7 +158,7 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
suite('File:', () => {
|
||||
|
||||
function getSimpleQuery(filePattern = ''): ISearchQuery {
|
||||
function getSimpleQuery(filePattern = ''): IFileQuery {
|
||||
return {
|
||||
type: QueryType.File,
|
||||
|
||||
@@ -168,7 +180,7 @@ suite('ExtHostSearch', () => {
|
||||
test('no results', async () => {
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -186,7 +198,7 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -200,7 +212,7 @@ suite('ExtHostSearch', () => {
|
||||
let cancelRequested = false;
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
return new TPromise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
token.onCancellationRequested(() => {
|
||||
cancelRequested = true;
|
||||
|
||||
@@ -234,7 +246,7 @@ suite('ExtHostSearch', () => {
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
assert(options.excludes.length === 2 && options.includes.length === 2, 'Missing global include/excludes');
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -270,7 +282,7 @@ suite('ExtHostSearch', () => {
|
||||
assert.deepEqual(options.excludes.sort(), ['*.js']);
|
||||
}
|
||||
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -307,7 +319,7 @@ suite('ExtHostSearch', () => {
|
||||
assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']);
|
||||
assert.deepEqual(options.excludes.sort(), []);
|
||||
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -347,7 +359,7 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
return TPromise.wrap(reportedResults
|
||||
return Promise.resolve(reportedResults
|
||||
.map(relativePath => joinPath(options.folder, relativePath)));
|
||||
}
|
||||
});
|
||||
@@ -393,7 +405,7 @@ suite('ExtHostSearch', () => {
|
||||
].map(relativePath => joinPath(rootFolderB, relativePath));
|
||||
}
|
||||
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -450,7 +462,7 @@ suite('ExtHostSearch', () => {
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -486,7 +498,7 @@ suite('ExtHostSearch', () => {
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -521,7 +533,7 @@ suite('ExtHostSearch', () => {
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -548,18 +560,16 @@ suite('ExtHostSearch', () => {
|
||||
test('multiroot max results', async () => {
|
||||
let cancels = 0;
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
async provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise<URI[]> {
|
||||
token.onCancellationRequested(() => cancels++);
|
||||
|
||||
// Provice results async so it has a chance to invoke every provider
|
||||
return new TPromise(r => process.nextTick(r))
|
||||
.then(() => {
|
||||
return [
|
||||
'file1.ts',
|
||||
'file2.ts',
|
||||
'file3.ts',
|
||||
].map(relativePath => joinPath(options.folder, relativePath));
|
||||
});
|
||||
await new Promise(r => process.nextTick(r));
|
||||
return [
|
||||
'file1.ts',
|
||||
'file2.ts',
|
||||
'file3.ts',
|
||||
].map(relativePath => joinPath(options.folder, relativePath));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -594,7 +604,7 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
await registerTestFileSearchProvider({
|
||||
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Thenable<URI[]> {
|
||||
return TPromise.wrap(reportedResults);
|
||||
return Promise.resolve(reportedResults);
|
||||
}
|
||||
}, fancyScheme);
|
||||
|
||||
@@ -615,24 +625,25 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
suite('Text:', () => {
|
||||
|
||||
function makePreview(text: string): vscode.TextSearchResult['preview'] {
|
||||
function makePreview(text: string): vscode.TextSearchMatch['preview'] {
|
||||
return {
|
||||
match: new Range(0, 0, 0, text.length),
|
||||
matches: new Range(0, 0, 0, text.length),
|
||||
text
|
||||
};
|
||||
}
|
||||
|
||||
function makeTextResult(baseFolder: URI, relativePath: string): vscode.TextSearchResult {
|
||||
function makeTextResult(baseFolder: URI, relativePath: string): vscode.TextSearchMatch {
|
||||
return {
|
||||
preview: makePreview('foo'),
|
||||
range: new Range(0, 0, 0, 3),
|
||||
ranges: new Range(0, 0, 0, 3),
|
||||
uri: joinPath(baseFolder, relativePath)
|
||||
};
|
||||
}
|
||||
|
||||
function getSimpleQuery(): ISearchQuery {
|
||||
function getSimpleQuery(queryText: string): ITextQuery {
|
||||
return {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern(queryText),
|
||||
|
||||
folderQueries: [
|
||||
{ folder: rootFolderA }
|
||||
@@ -650,11 +661,25 @@ suite('ExtHostSearch', () => {
|
||||
const actualTextSearchResults: vscode.TextSearchResult[] = [];
|
||||
for (let fileMatch of actual) {
|
||||
// Make relative
|
||||
for (let lineMatch of fileMatch.lineMatches) {
|
||||
for (let [offset, length] of lineMatch.offsetAndLengths) {
|
||||
for (let lineResult of fileMatch.results) {
|
||||
if (resultIsMatch(lineResult)) {
|
||||
actualTextSearchResults.push({
|
||||
preview: { text: lineMatch.preview, match: null },
|
||||
range: new Range(lineMatch.lineNumber, offset, lineMatch.lineNumber, length + offset),
|
||||
preview: {
|
||||
text: lineResult.preview.text,
|
||||
matches: mapArrayOrNot(
|
||||
lineResult.preview.matches,
|
||||
m => new Range(m.startLineNumber, m.startColumn, m.endLineNumber, m.endColumn))
|
||||
},
|
||||
ranges: mapArrayOrNot(
|
||||
lineResult.ranges,
|
||||
r => new Range(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn),
|
||||
),
|
||||
uri: fileMatch.resource
|
||||
});
|
||||
} else {
|
||||
actualTextSearchResults.push(<vscode.TextSearchContext>{
|
||||
text: lineResult.text,
|
||||
lineNumber: lineResult.lineNumber,
|
||||
uri: fileMatch.resource
|
||||
});
|
||||
}
|
||||
@@ -664,18 +689,23 @@ suite('ExtHostSearch', () => {
|
||||
const rangeToString = (r: vscode.Range) => `(${r.start.line}, ${r.start.character}), (${r.end.line}, ${r.end.character})`;
|
||||
|
||||
const makeComparable = (results: vscode.TextSearchResult[]) => results
|
||||
.sort((a, b) => b.preview.text.localeCompare(a.preview.text))
|
||||
.map(r => ({
|
||||
...r,
|
||||
...{
|
||||
uri: r.uri.toString(),
|
||||
range: rangeToString(r.range),
|
||||
preview: {
|
||||
text: r.preview.text,
|
||||
match: null // Don't care about this right now
|
||||
}
|
||||
.sort((a, b) => {
|
||||
const compareKeyA = a.uri.toString() + ': ' + (extensionResultIsMatch(a) ? a.preview.text : a.text);
|
||||
const compareKeyB = b.uri.toString() + ': ' + (extensionResultIsMatch(b) ? b.preview.text : b.text);
|
||||
return compareKeyB.localeCompare(compareKeyA);
|
||||
})
|
||||
.map(r => extensionResultIsMatch(r) ? {
|
||||
uri: r.uri.toString(),
|
||||
range: mapArrayOrNot(r.ranges, rangeToString),
|
||||
preview: {
|
||||
text: r.preview.text,
|
||||
match: null // Don't care about this right now
|
||||
}
|
||||
}));
|
||||
} : {
|
||||
uri: r.uri.toString(),
|
||||
text: r.text,
|
||||
lineNumber: r.lineNumber
|
||||
});
|
||||
|
||||
return assert.deepEqual(
|
||||
makeComparable(actualTextSearchResults),
|
||||
@@ -684,12 +714,12 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
test('no results', async () => {
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
return TPromise.wrap(null);
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const { results, stats } = await runTextSearch(getPattern('foo'), getSimpleQuery());
|
||||
const { results, stats } = await runTextSearch(getSimpleQuery('foo'));
|
||||
assert(!stats.limitHit);
|
||||
assert(!results.length);
|
||||
});
|
||||
@@ -701,28 +731,29 @@ suite('ExtHostSearch', () => {
|
||||
];
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const { results, stats } = await runTextSearch(getPattern('foo'), getSimpleQuery());
|
||||
const { results, stats } = await runTextSearch(getSimpleQuery('foo'));
|
||||
assert(!stats.limitHit);
|
||||
assertResults(results, providedResults);
|
||||
});
|
||||
|
||||
test('all provider calls get global include/excludes', async () => {
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
assert.equal(options.includes.length, 1);
|
||||
assert.equal(options.excludes.length, 1);
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: IRawSearchQuery = {
|
||||
const query: ITextQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
includePattern: {
|
||||
'*.ts': true
|
||||
@@ -738,12 +769,12 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
await runTextSearch(getPattern('foo'), query);
|
||||
await runTextSearch(query);
|
||||
});
|
||||
|
||||
test('global/local include/excludes combined', async () => {
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
if (options.folder.toString() === rootFolderA.toString()) {
|
||||
assert.deepEqual(options.includes.sort(), ['*.ts', 'foo']);
|
||||
assert.deepEqual(options.excludes.sort(), ['*.js', 'bar']);
|
||||
@@ -752,12 +783,13 @@ suite('ExtHostSearch', () => {
|
||||
assert.deepEqual(options.excludes.sort(), ['*.js']);
|
||||
}
|
||||
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: IRawSearchQuery = {
|
||||
const query: ITextQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
includePattern: {
|
||||
'*.ts': true
|
||||
@@ -779,21 +811,22 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
await runTextSearch(getPattern('foo'), query);
|
||||
await runTextSearch(query);
|
||||
});
|
||||
|
||||
test('include/excludes resolved correctly', async () => {
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']);
|
||||
assert.deepEqual(options.excludes.sort(), []);
|
||||
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
includePattern: {
|
||||
'*.ts': true,
|
||||
@@ -816,18 +849,18 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
await runTextSearch(getPattern('foo'), query);
|
||||
await runTextSearch(query);
|
||||
});
|
||||
|
||||
test('provider fail', async () => {
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
throw new Error('Provider fail');
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await runTextSearch(getPattern('foo'), getSimpleQuery());
|
||||
await runTextSearch(getSimpleQuery('foo'));
|
||||
assert(false, 'Expected to fail');
|
||||
} catch {
|
||||
// expected to fail
|
||||
@@ -852,14 +885,15 @@ suite('ExtHostSearch', () => {
|
||||
];
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
excludePattern: {
|
||||
'*.js': {
|
||||
@@ -872,7 +906,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results } = await runTextSearch(query);
|
||||
assertResults(results, providedResults.slice(1));
|
||||
});
|
||||
|
||||
@@ -896,7 +930,7 @@ suite('ExtHostSearch', () => {
|
||||
};
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
let reportedResults;
|
||||
if (options.folder.fsPath === rootFolderA.fsPath) {
|
||||
reportedResults = [
|
||||
@@ -913,12 +947,13 @@ suite('ExtHostSearch', () => {
|
||||
}
|
||||
|
||||
reportedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
excludePattern: {
|
||||
'*.js': {
|
||||
@@ -944,7 +979,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results } = await runTextSearch(query);
|
||||
assertResults(results, [
|
||||
makeTextResult(rootFolderA, 'folder/fileA.scss'),
|
||||
makeTextResult(rootFolderA, 'folder/file2.css'),
|
||||
@@ -960,14 +995,15 @@ suite('ExtHostSearch', () => {
|
||||
];
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
includePattern: {
|
||||
'*.ts': true
|
||||
@@ -978,7 +1014,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results } = await runTextSearch(query);
|
||||
assertResults(results, providedResults.slice(1));
|
||||
});
|
||||
|
||||
@@ -990,15 +1026,16 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
let wasCanceled = false;
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
maxResults: 1,
|
||||
|
||||
@@ -1007,7 +1044,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results, stats } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results, stats } = await runTextSearch(query);
|
||||
assert(stats.limitHit, 'Expected to return limitHit');
|
||||
assertResults(results, providedResults.slice(0, 1));
|
||||
assert(wasCanceled, 'Expected to be canceled');
|
||||
@@ -1022,15 +1059,16 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
let wasCanceled = false;
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
maxResults: 2,
|
||||
|
||||
@@ -1039,7 +1077,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results, stats } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results, stats } = await runTextSearch(query);
|
||||
assert(stats.limitHit, 'Expected to return limitHit');
|
||||
assertResults(results, providedResults.slice(0, 2));
|
||||
assert(wasCanceled, 'Expected to be canceled');
|
||||
@@ -1053,15 +1091,16 @@ suite('ExtHostSearch', () => {
|
||||
|
||||
let wasCanceled = false;
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
token.onCancellationRequested(() => wasCanceled = true);
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
maxResults: 2,
|
||||
|
||||
@@ -1070,30 +1109,60 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results, stats } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results, stats } = await runTextSearch(query);
|
||||
assert(!stats.limitHit, 'Expected not to return limitHit');
|
||||
assertResults(results, providedResults);
|
||||
assert(!wasCanceled, 'Expected not to be canceled');
|
||||
});
|
||||
|
||||
test('multiroot max results', async () => {
|
||||
let cancels = 0;
|
||||
test('provider returns early with limitHit', async () => {
|
||||
const providedResults: vscode.TextSearchResult[] = [
|
||||
makeTextResult(rootFolderA, 'file1.ts'),
|
||||
makeTextResult(rootFolderA, 'file2.ts'),
|
||||
makeTextResult(rootFolderA, 'file3.ts')
|
||||
];
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
token.onCancellationRequested(() => cancels++);
|
||||
return new TPromise(r => process.nextTick(r))
|
||||
.then(() => {
|
||||
[
|
||||
'file1.ts',
|
||||
'file2.ts',
|
||||
'file3.ts',
|
||||
].forEach(f => progress.report(makeTextResult(options.folder, f)));
|
||||
});
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return Promise.resolve({ limitHit: true });
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
maxResults: 1000,
|
||||
|
||||
folderQueries: [
|
||||
{ folder: rootFolderA }
|
||||
]
|
||||
};
|
||||
|
||||
const { results, stats } = await runTextSearch(query);
|
||||
assert(stats.limitHit, 'Expected to return limitHit');
|
||||
assertResults(results, providedResults);
|
||||
});
|
||||
|
||||
test('multiroot max results', async () => {
|
||||
let cancels = 0;
|
||||
await registerTestTextSearchProvider({
|
||||
async provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Promise<vscode.TextSearchComplete> {
|
||||
token.onCancellationRequested(() => cancels++);
|
||||
await new Promise(r => process.nextTick(r));
|
||||
[
|
||||
'file1.ts',
|
||||
'file2.ts',
|
||||
'file3.ts',
|
||||
].forEach(f => progress.report(makeTextResult(options.folder, f)));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
maxResults: 2,
|
||||
|
||||
@@ -1103,7 +1172,7 @@ suite('ExtHostSearch', () => {
|
||||
]
|
||||
};
|
||||
|
||||
const { results } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results } = await runTextSearch(query);
|
||||
assert.equal(results.length, 2);
|
||||
assert.equal(cancels, 2);
|
||||
});
|
||||
@@ -1116,21 +1185,22 @@ suite('ExtHostSearch', () => {
|
||||
];
|
||||
|
||||
await registerTestTextSearchProvider({
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<void> {
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Thenable<vscode.TextSearchComplete> {
|
||||
providedResults.forEach(r => progress.report(r));
|
||||
return TPromise.wrap(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
}, fancyScheme);
|
||||
|
||||
const query: ISearchQuery = {
|
||||
type: QueryType.Text,
|
||||
contentPattern: getPattern('foo'),
|
||||
|
||||
folderQueries: [
|
||||
{ folder: fancySchemeFolderA }
|
||||
]
|
||||
};
|
||||
|
||||
const { results } = await runTextSearch(getPattern('foo'), query);
|
||||
const { results } = await runTextSearch(query);
|
||||
assertResults(results, providedResults);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { TextEditorLineNumbersStyle, Range } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { MainThreadTextEditorsShape, IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { ExtHostTextEditorOptions, ExtHostTextEditor } from 'vs/workbench/api/node/extHostTextEditor';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/node/extHostDocumentData';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
|
||||
suite('ExtHostTextEditor', () => {
|
||||
@@ -44,9 +41,9 @@ suite('ExtHostTextEditor', () => {
|
||||
test('API [bug]: registerTextEditorCommand clears redo stack even if no edits are made #55163', async function () {
|
||||
let applyCount = 0;
|
||||
let editor = new ExtHostTextEditor(new class extends mock<MainThreadTextEditorsShape>() {
|
||||
$tryApplyEdits(): TPromise<boolean> {
|
||||
$tryApplyEdits(): Promise<boolean> {
|
||||
applyCount += 1;
|
||||
return TPromise.wrap(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}, 'edt1', doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1);
|
||||
|
||||
@@ -73,7 +70,7 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
$trySetOptions: (id: string, options: ITextEditorConfigurationUpdate) => {
|
||||
assert.equal(id, '1');
|
||||
calls.push(options);
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
},
|
||||
$tryShowTextDocument: undefined,
|
||||
$registerTextEditorDecorationType: undefined,
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
|
||||
import { MainContext, MainThreadTextEditorsShape, WorkspaceEditDto } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
|
||||
import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol';
|
||||
@@ -26,9 +23,9 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => {
|
||||
|
||||
let rpcProtocol = new TestRPCProtocol();
|
||||
rpcProtocol.set(MainContext.MainThreadTextEditors, new class extends mock<MainThreadTextEditorsShape>() {
|
||||
$tryApplyWorkspaceEdit(_workspaceResourceEdits: WorkspaceEditDto): TPromise<boolean> {
|
||||
$tryApplyWorkspaceEdit(_workspaceResourceEdits: WorkspaceEditDto): Promise<boolean> {
|
||||
workspaceResourceEdits = _workspaceResourceEdits;
|
||||
return TPromise.as(true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
});
|
||||
const documentsAndEditors = new ExtHostDocumentsAndEditors(SingleProxyRPCProtocol(null));
|
||||
@@ -45,22 +42,20 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => {
|
||||
editors = new ExtHostEditors(rpcProtocol, documentsAndEditors);
|
||||
});
|
||||
|
||||
test('uses version id if document available', () => {
|
||||
test('uses version id if document available', async () => {
|
||||
let edit = new extHostTypes.WorkspaceEdit();
|
||||
edit.replace(resource, new extHostTypes.Range(0, 0, 0, 0), 'hello');
|
||||
return editors.applyWorkspaceEdit(edit).then((result) => {
|
||||
assert.equal(workspaceResourceEdits.edits.length, 1);
|
||||
assert.equal((<ResourceTextEdit>workspaceResourceEdits.edits[0]).modelVersionId, 1337);
|
||||
});
|
||||
await editors.applyWorkspaceEdit(edit);
|
||||
assert.equal(workspaceResourceEdits.edits.length, 1);
|
||||
assert.equal((<ResourceTextEdit>workspaceResourceEdits.edits[0]).modelVersionId, 1337);
|
||||
});
|
||||
|
||||
test('does not use version id if document is not available', () => {
|
||||
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');
|
||||
return editors.applyWorkspaceEdit(edit).then((result) => {
|
||||
assert.equal(workspaceResourceEdits.edits.length, 1);
|
||||
assert.ok(typeof (<ResourceTextEdit>workspaceResourceEdits.edits[0]).modelVersionId === 'undefined');
|
||||
});
|
||||
await editors.applyWorkspaceEdit(edit);
|
||||
assert.equal(workspaceResourceEdits.edits.length, 1);
|
||||
assert.ok(typeof (<ResourceTextEdit>workspaceResourceEdits.edits[0]).modelVersionId === 'undefined');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
@@ -18,9 +16,9 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
|
||||
import { MainThreadCommands } from 'vs/workbench/api/electron-browser/mainThreadCommands';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
suite('ExtHostTreeView', function () {
|
||||
|
||||
@@ -31,11 +29,11 @@ suite('ExtHostTreeView', function () {
|
||||
$registerTreeViewDataProvider(treeViewId: string): void {
|
||||
}
|
||||
|
||||
$refresh(viewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): TPromise<void> {
|
||||
return TPromise.as(null).then(() => this.onRefresh.fire(itemsToRefresh));
|
||||
$refresh(viewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise<void> {
|
||||
return Promise.resolve(null).then(() => this.onRefresh.fire(itemsToRefresh));
|
||||
}
|
||||
|
||||
$reveal(): TPromise<void> {
|
||||
$reveal(): Promise<void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -75,8 +73,9 @@ suite('ExtHostTreeView', function () {
|
||||
testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService()), new NullLogService());
|
||||
onDidChangeTreeNode = new Emitter<{ key: string }>();
|
||||
onDidChangeTreeNodeWithId = new Emitter<{ key: string }>();
|
||||
testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() });
|
||||
testObject.createTreeView('testNodeWithIdTreeProvider', { treeDataProvider: aNodeWithIdTreeDataProvider() });
|
||||
testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
testObject.createTreeView('testNodeWithIdTreeProvider', { treeDataProvider: aNodeWithIdTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
testObject.createTreeView('testNodeWithHighlightsTreeProvider', { treeDataProvider: aNodeWithHighlightedLabelTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
|
||||
return loadCompleteTree('testNodeTreeProvider');
|
||||
});
|
||||
@@ -86,12 +85,12 @@ suite('ExtHostTreeView', function () {
|
||||
.then(elements => {
|
||||
const actuals = elements.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['0/0:a', '0/0:b']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeTreeProvider', '0/0:a')
|
||||
.then(children => {
|
||||
const actuals = children.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['0/0:a/0:aa', '0/0:a/0:ab']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeTreeProvider', '0/0:a/0:aa').then(children => assert.equal(children.length, 0)),
|
||||
testObject.$getChildren('testNodeTreeProvider', '0/0:a/0:ab').then(children => assert.equal(children.length, 0))
|
||||
]);
|
||||
@@ -100,7 +99,7 @@ suite('ExtHostTreeView', function () {
|
||||
.then(children => {
|
||||
const actuals = children.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['0/0:b/0:ba', '0/0:b/0:bb']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeTreeProvider', '0/0:b/0:ba').then(children => assert.equal(children.length, 0)),
|
||||
testObject.$getChildren('testNodeTreeProvider', '0/0:b/0:bb').then(children => assert.equal(children.length, 0))
|
||||
]);
|
||||
@@ -114,12 +113,12 @@ suite('ExtHostTreeView', function () {
|
||||
.then(elements => {
|
||||
const actuals = elements.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['1/a', '1/b']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeWithIdTreeProvider', '1/a')
|
||||
.then(children => {
|
||||
const actuals = children.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['1/aa', '1/ab']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeWithIdTreeProvider', '1/aa').then(children => assert.equal(children.length, 0)),
|
||||
testObject.$getChildren('testNodeWithIdTreeProvider', '1/ab').then(children => assert.equal(children.length, 0))
|
||||
]);
|
||||
@@ -128,7 +127,7 @@ suite('ExtHostTreeView', function () {
|
||||
.then(children => {
|
||||
const actuals = children.map(e => e.handle);
|
||||
assert.deepEqual(actuals, ['1/ba', '1/bb']);
|
||||
return TPromise.join([
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeWithIdTreeProvider', '1/ba').then(children => assert.equal(children.length, 0)),
|
||||
testObject.$getChildren('testNodeWithIdTreeProvider', '1/bb').then(children => assert.equal(children.length, 0))
|
||||
]);
|
||||
@@ -137,6 +136,51 @@ suite('ExtHostTreeView', function () {
|
||||
});
|
||||
});
|
||||
|
||||
test('construct highlights tree', () => {
|
||||
return testObject.$getChildren('testNodeWithHighlightsTreeProvider')
|
||||
.then(elements => {
|
||||
assert.deepEqual(removeUnsetKeys(elements), [{
|
||||
handle: '1/a',
|
||||
label: { label: 'a', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
}, {
|
||||
handle: '1/b',
|
||||
label: { label: 'b', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
}]);
|
||||
return Promise.all([
|
||||
testObject.$getChildren('testNodeWithHighlightsTreeProvider', '1/a')
|
||||
.then(children => {
|
||||
assert.deepEqual(removeUnsetKeys(children), [{
|
||||
handle: '1/aa',
|
||||
parentHandle: '1/a',
|
||||
label: { label: 'aa', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
}, {
|
||||
handle: '1/ab',
|
||||
parentHandle: '1/a',
|
||||
label: { label: 'ab', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
}]);
|
||||
}),
|
||||
testObject.$getChildren('testNodeWithHighlightsTreeProvider', '1/b')
|
||||
.then(children => {
|
||||
assert.deepEqual(removeUnsetKeys(children), [{
|
||||
handle: '1/ba',
|
||||
parentHandle: '1/b',
|
||||
label: { label: 'ba', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
}, {
|
||||
handle: '1/bb',
|
||||
parentHandle: '1/b',
|
||||
label: { label: 'bb', highlights: [[0, 2], [3, 5]] },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
}]);
|
||||
})
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('error is thrown if id is not unique', (done) => {
|
||||
tree['a'] = {
|
||||
'aa': {},
|
||||
@@ -167,12 +211,12 @@ suite('ExtHostTreeView', function () {
|
||||
});
|
||||
|
||||
test('refresh a parent node', () => {
|
||||
return new TPromise((c, e) => {
|
||||
return new Promise((c, e) => {
|
||||
target.onRefresh.event(actuals => {
|
||||
assert.deepEqual(['0/0:b'], Object.keys(actuals));
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), {
|
||||
handle: '0/0:b',
|
||||
label: 'b',
|
||||
label: { label: 'b' },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
});
|
||||
c(null);
|
||||
@@ -187,7 +231,7 @@ suite('ExtHostTreeView', function () {
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:b/0:bb']), {
|
||||
handle: '0/0:b/0:bb',
|
||||
parentHandle: '0/0:b',
|
||||
label: 'bb',
|
||||
label: { label: 'bb' },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
});
|
||||
done();
|
||||
@@ -200,13 +244,13 @@ suite('ExtHostTreeView', function () {
|
||||
assert.deepEqual(['0/0:b', '0/0:a/0:aa'], Object.keys(actuals));
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), {
|
||||
handle: '0/0:b',
|
||||
label: 'b',
|
||||
label: { label: 'b' },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
});
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:a/0:aa']), {
|
||||
handle: '0/0:a/0:aa',
|
||||
parentHandle: '0/0:a',
|
||||
label: 'aa',
|
||||
label: { label: 'aa' },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
});
|
||||
done();
|
||||
@@ -221,13 +265,13 @@ suite('ExtHostTreeView', function () {
|
||||
assert.deepEqual(['0/0:a/0:aa', '0/0:b'], Object.keys(actuals));
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), {
|
||||
handle: '0/0:b',
|
||||
label: 'b',
|
||||
label: { label: 'b' },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
});
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:a/0:aa']), {
|
||||
handle: '0/0:a/0:aa',
|
||||
parentHandle: '0/0:a',
|
||||
label: 'aa',
|
||||
label: { label: 'aa' },
|
||||
collapsibleState: TreeItemCollapsibleState.None
|
||||
});
|
||||
done();
|
||||
@@ -243,7 +287,7 @@ suite('ExtHostTreeView', function () {
|
||||
assert.deepEqual(['0/0:a'], Object.keys(actuals));
|
||||
assert.deepEqual(removeUnsetKeys(actuals['0/0:a']), {
|
||||
handle: '0/0:aa',
|
||||
label: 'aa',
|
||||
label: { label: 'aa' },
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed
|
||||
});
|
||||
done();
|
||||
@@ -402,49 +446,49 @@ suite('ExtHostTreeView', function () {
|
||||
});
|
||||
|
||||
test('reveal will throw an error if getParent is not implemented', () => {
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aNodeTreeDataProvider() });
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
return treeView.reveal({ key: 'a' })
|
||||
.then(() => assert.fail('Reveal should throw an error as getParent is not implemented'), () => null);
|
||||
});
|
||||
|
||||
test('reveal will return empty array for root element', () => {
|
||||
const revealTarget = sinon.spy(target, '$reveal');
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() });
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
return treeView.reveal({ key: 'a' })
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepEqual({ handle: '0/0:a', label: 'a', collapsibleState: TreeItemCollapsibleState.Collapsed }, removeUnsetKeys(revealTarget.args[0][1]));
|
||||
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 }, revealTarget.args[0][3]);
|
||||
assert.deepEqual({ select: true, focus: false, expand: false }, revealTarget.args[0][3]);
|
||||
});
|
||||
});
|
||||
|
||||
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() });
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
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: 'aa', collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' }, removeUnsetKeys(revealTarget.args[0][1]));
|
||||
assert.deepEqual([{ handle: '0/0:a', label: 'a', collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepEqual({ select: true, focus: false }, revealTarget.args[0][3]);
|
||||
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]);
|
||||
});
|
||||
});
|
||||
|
||||
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() });
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
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: 'aa', collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:a' }, removeUnsetKeys(revealTarget.args[0][1]));
|
||||
assert.deepEqual([{ handle: '0/0:a', label: 'a', collapsibleState: TreeItemCollapsibleState.Collapsed }], (<Array<any>>revealTarget.args[0][2]).map(arg => removeUnsetKeys(arg)));
|
||||
assert.deepEqual({ select: true, focus: false }, revealTarget.args[0][3]);
|
||||
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]);
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -457,34 +501,108 @@ suite('ExtHostTreeView', function () {
|
||||
}
|
||||
};
|
||||
const revealTarget = sinon.spy(target, '$reveal');
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() });
|
||||
return treeView.reveal({ key: 'bac' }, { select: false, focus: false })
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
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: 'bac', collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b/0:ba' }, removeUnsetKeys(revealTarget.args[0][1]));
|
||||
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: 'b', collapsibleState: TreeItemCollapsibleState.Collapsed },
|
||||
{ handle: '0/0:b/0:ba', label: 'ba', collapsibleState: TreeItemCollapsibleState.Collapsed, parentHandle: '0/0:b' }
|
||||
{ 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 }, revealTarget.args[0][3]);
|
||||
assert.deepEqual({ select: false, focus: false, expand: false }, revealTarget.args[0][3]);
|
||||
});
|
||||
});
|
||||
|
||||
function loadCompleteTree(treeId, element?: string): TPromise<void> {
|
||||
test('reveal after first udpate', () => {
|
||||
const revealTarget = sinon.spy(target, '$reveal');
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
return loadCompleteTree('treeDataProvider')
|
||||
.then(() => {
|
||||
tree = {
|
||||
'a': {
|
||||
'aa': {},
|
||||
'ac': {}
|
||||
},
|
||||
'b': {
|
||||
'ba': {},
|
||||
'bb': {}
|
||||
}
|
||||
};
|
||||
onDidChangeTreeNode.fire(getNode('a'));
|
||||
|
||||
return treeView.reveal({ key: 'ac' })
|
||||
.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]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('reveal after second udpate', () => {
|
||||
const revealTarget = sinon.spy(target, '$reveal');
|
||||
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription);
|
||||
return loadCompleteTree('treeDataProvider')
|
||||
.then(() => {
|
||||
tree = {
|
||||
'a': {
|
||||
'aa': {},
|
||||
'ac': {}
|
||||
},
|
||||
'b': {
|
||||
'ba': {},
|
||||
'bb': {}
|
||||
}
|
||||
};
|
||||
onDidChangeTreeNode.fire(getNode('a'));
|
||||
tree = {
|
||||
'a': {
|
||||
'aa': {},
|
||||
'ac': {}
|
||||
},
|
||||
'b': {
|
||||
'ba': {},
|
||||
'bc': {}
|
||||
}
|
||||
};
|
||||
onDidChangeTreeNode.fire(getNode('b'));
|
||||
|
||||
return treeView.reveal({ key: 'bc' })
|
||||
.then(() => {
|
||||
assert.ok(revealTarget.calledOnce);
|
||||
assert.deepEqual('treeDataProvider', revealTarget.args[0][0]);
|
||||
assert.deepEqual({ handle: '0/0:b/0:bc', label: { label: 'bc' }, collapsibleState: TreeItemCollapsibleState.None, parentHandle: '0/0:b' }, removeUnsetKeys(revealTarget.args[0][1]));
|
||||
assert.deepEqual([{ handle: '0/0:b', label: { label: 'b' }, 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]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function loadCompleteTree(treeId, element?: string) {
|
||||
return testObject.$getChildren(treeId, element)
|
||||
.then(elements => elements.map(e => loadCompleteTree(treeId, e.handle)))
|
||||
.then(() => null);
|
||||
}
|
||||
|
||||
function removeUnsetKeys(obj: any): any {
|
||||
const result = {};
|
||||
for (const key of Object.keys(obj)) {
|
||||
if (obj[key] !== void 0) {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(o => removeUnsetKeys(o));
|
||||
}
|
||||
return result;
|
||||
|
||||
if (typeof obj === 'object') {
|
||||
const result = {};
|
||||
for (const key of Object.keys(obj)) {
|
||||
if (obj[key] !== void 0) {
|
||||
result[key] = removeUnsetKeys(obj[key]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function aNodeTreeDataProvider(): TreeDataProvider<{ key: string }> {
|
||||
@@ -529,6 +647,20 @@ suite('ExtHostTreeView', function () {
|
||||
};
|
||||
}
|
||||
|
||||
function aNodeWithHighlightedLabelTreeDataProvider(): TreeDataProvider<{ key: string }> {
|
||||
return {
|
||||
getChildren: (element: { key: string }): { key: string }[] => {
|
||||
return getChildren(element ? element.key : undefined).map(key => getNode(key));
|
||||
},
|
||||
getTreeItem: (element: { key: string }): TreeItem => {
|
||||
const treeItem = getTreeItem(element.key, [[0, 2], [3, 5]]);
|
||||
treeItem.id = element.key;
|
||||
return treeItem;
|
||||
},
|
||||
onDidChangeTreeData: onDidChangeTreeNodeWithId.event
|
||||
};
|
||||
}
|
||||
|
||||
function getTreeElement(element): any {
|
||||
let parent = tree;
|
||||
for (let i = 0; i < element.length; i++) {
|
||||
@@ -551,10 +683,10 @@ suite('ExtHostTreeView', function () {
|
||||
return [];
|
||||
}
|
||||
|
||||
function getTreeItem(key: string): TreeItem {
|
||||
function getTreeItem(key: string, highlights?: [number, number][]): TreeItem {
|
||||
const treeElement = getTreeElement(key);
|
||||
return {
|
||||
label: labels[key] || key,
|
||||
label: <any>{ label: labels[key] || key, highlights },
|
||||
collapsibleState: treeElement && Object.keys(treeElement).length ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None
|
||||
};
|
||||
}
|
||||
@@ -570,4 +702,4 @@ suite('ExtHostTreeView', function () {
|
||||
constructor(readonly key: string) { }
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { MarkdownString, LogLevel } from 'vs/workbench/api/node/extHostTypeConverters';
|
||||
import { isEmptyObject } from 'vs/base/common/types';
|
||||
import { size } from 'vs/base/common/collections';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
|
||||
|
||||
suite('ExtHostTypeConverter', function () {
|
||||
|
||||
test('MarkdownConvert - uris', function () {
|
||||
|
||||
let data = MarkdownString.from('Hello');
|
||||
assert.equal(isEmptyObject(data.uris), true);
|
||||
assert.equal(data.value, 'Hello');
|
||||
|
||||
data = MarkdownString.from('Hello [link](foo)');
|
||||
assert.equal(data.value, 'Hello [link](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(isEmptyObject(data.uris), true); // no scheme, no uri
|
||||
|
||||
data = MarkdownString.from('Hello [link](foo:path)');
|
||||
assert.equal(data.value, 'Hello [link](foo:path)');
|
||||
assert.equal(size(data.uris), 1);
|
||||
assert.ok(!!data.uris['foo:path']);
|
||||
|
||||
data = MarkdownString.from('hello@foo.bar');
|
||||
assert.equal(data.value, 'hello@foo.bar');
|
||||
assert.equal(size(data.uris), 1);
|
||||
assert.ok(!!data.uris['mailto:hello@foo.bar']);
|
||||
|
||||
data = MarkdownString.from('*hello* [click](command:me)');
|
||||
assert.equal(data.value, '*hello* [click](command:me)');
|
||||
assert.equal(size(data.uris), 1);
|
||||
assert.ok(!!data.uris['command:me']);
|
||||
|
||||
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
|
||||
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
|
||||
assert.equal(size(data.uris), 1);
|
||||
assert.ok(!!data.uris['file:///somepath/here']);
|
||||
|
||||
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
|
||||
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
|
||||
assert.equal(size(data.uris), 1);
|
||||
assert.ok(!!data.uris['file:///somepath/here']);
|
||||
|
||||
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here2)');
|
||||
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here2)');
|
||||
assert.equal(size(data.uris), 2);
|
||||
assert.ok(!!data.uris['file:///somepath/here']);
|
||||
assert.ok(!!data.uris['file:///somepath/here2']);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as types from 'vs/workbench/api/node/extHostTypes';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
@@ -45,7 +43,7 @@ suite('ExtHostTypes', function () {
|
||||
});
|
||||
});
|
||||
|
||||
test('Disposable', function () {
|
||||
test('Disposable', () => {
|
||||
|
||||
let count = 0;
|
||||
let d = new types.Disposable(() => {
|
||||
@@ -72,7 +70,7 @@ suite('ExtHostTypes', function () {
|
||||
|
||||
});
|
||||
|
||||
test('Position', function () {
|
||||
test('Position', () => {
|
||||
assert.throws(() => new types.Position(-1, 0));
|
||||
assert.throws(() => new types.Position(0, -1));
|
||||
|
||||
@@ -187,7 +185,7 @@ suite('ExtHostTypes', function () {
|
||||
assert.throws(() => p1.with({ character: -1 }));
|
||||
});
|
||||
|
||||
test('Range', function () {
|
||||
test('Range', () => {
|
||||
assert.throws(() => new types.Range(-1, 0, 0, 0));
|
||||
assert.throws(() => new types.Range(0, -1, 0, 0));
|
||||
assert.throws(() => new types.Range(new types.Position(0, 0), undefined));
|
||||
@@ -331,7 +329,7 @@ suite('ExtHostTypes', function () {
|
||||
assert.throws(() => range.with(undefined, null));
|
||||
});
|
||||
|
||||
test('TextEdit', function () {
|
||||
test('TextEdit', () => {
|
||||
|
||||
let range = new types.Range(1, 1, 2, 11);
|
||||
let edit = new types.TextEdit(range, undefined);
|
||||
@@ -345,7 +343,7 @@ suite('ExtHostTypes', function () {
|
||||
assert.equal(edit.newText, '');
|
||||
});
|
||||
|
||||
test('WorkspaceEdit', function () {
|
||||
test('WorkspaceEdit', () => {
|
||||
|
||||
let a = URI.file('a.ts');
|
||||
let b = URI.file('b.ts');
|
||||
@@ -386,12 +384,12 @@ suite('ExtHostTypes', function () {
|
||||
const all = edit._allEntries();
|
||||
assert.equal(all.length, 4);
|
||||
|
||||
function isFileChange(thing: [URI, types.TextEdit[]] | [URI, URI, { overwrite?: boolean }]): thing is [URI, URI, { overwrite?: boolean }] {
|
||||
function isFileChange(thing: [URI, types.TextEdit[]] | [URI?, URI?, { overwrite?: boolean }?]): thing is [URI?, URI?, { overwrite?: boolean }?] {
|
||||
const [f, s] = thing;
|
||||
return URI.isUri(f) && URI.isUri(s);
|
||||
}
|
||||
|
||||
function isTextChange(thing: [URI, types.TextEdit[]] | [URI, URI, { overwrite?: boolean }]): thing is [URI, types.TextEdit[]] {
|
||||
function isTextChange(thing: [URI, types.TextEdit[]] | [URI?, URI?, { overwrite?: boolean }?]): thing is [URI, types.TextEdit[]] {
|
||||
const [f, s] = thing;
|
||||
return URI.isUri(f) && Array.isArray(s);
|
||||
}
|
||||
@@ -424,7 +422,7 @@ suite('ExtHostTypes', function () {
|
||||
assert.equal((second as [URI, types.TextEdit[]])[1][0].newText, 'Foo');
|
||||
});
|
||||
|
||||
test('DocumentLink', function () {
|
||||
test('DocumentLink', () => {
|
||||
assert.throws(() => new types.DocumentLink(null, null));
|
||||
assert.throws(() => new types.DocumentLink(new types.Range(1, 1, 1, 1), null));
|
||||
});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MainThreadWebviews } from 'vs/workbench/api/electron-browser/mainThreadWebview';
|
||||
import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview';
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { basename } from 'path';
|
||||
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
|
||||
import { TestRPCProtocol } from './testRPCProtocol';
|
||||
@@ -15,6 +13,7 @@ import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace';
|
||||
import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { IMainContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { Counter } from 'vs/base/common/numbers';
|
||||
|
||||
suite('ExtHostWorkspace', function () {
|
||||
|
||||
@@ -39,9 +38,9 @@ suite('ExtHostWorkspace', function () {
|
||||
}
|
||||
}
|
||||
|
||||
test('asRelativePath', function () {
|
||||
test('asRelativePath', () => {
|
||||
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
|
||||
assertAsRelativePath(ws, '/Coding/Applications/NewsWoWBot/bernd/das/brot', 'bernd/das/brot');
|
||||
assertAsRelativePath(ws, '/Apps/DartPubCache/hosted/pub.dartlang.org/convert-2.0.1/lib/src/hex.dart',
|
||||
@@ -55,7 +54,7 @@ suite('ExtHostWorkspace', function () {
|
||||
test('asRelativePath, same paths, #11402', function () {
|
||||
const root = '/home/aeschli/workspaces/samples/docker';
|
||||
const input = '/home/aeschli/workspaces/samples/docker';
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
|
||||
assertAsRelativePath(ws, (input), input);
|
||||
|
||||
@@ -64,20 +63,20 @@ suite('ExtHostWorkspace', function () {
|
||||
});
|
||||
|
||||
test('asRelativePath, no workspace', function () {
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter());
|
||||
assertAsRelativePath(ws, (''), '');
|
||||
assertAsRelativePath(ws, ('/foo/bar'), '/foo/bar');
|
||||
});
|
||||
|
||||
test('asRelativePath, multiple folders', function () {
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
assertAsRelativePath(ws, '/Coding/One/file.txt', 'One/file.txt');
|
||||
assertAsRelativePath(ws, '/Coding/Two/files/out.txt', 'Two/files/out.txt');
|
||||
assertAsRelativePath(ws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt');
|
||||
});
|
||||
|
||||
test('slightly inconsistent behaviour of asRelativePath and getWorkspaceFolder, #31553', function () {
|
||||
const mrws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService());
|
||||
const mrws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
|
||||
assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt');
|
||||
assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt', true);
|
||||
@@ -89,7 +88,7 @@ suite('ExtHostWorkspace', function () {
|
||||
assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', true);
|
||||
assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', false);
|
||||
|
||||
const srws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService());
|
||||
const srws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt');
|
||||
assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt', false);
|
||||
assertAsRelativePath(srws, '/Coding/One/file.txt', 'One/file.txt', true);
|
||||
@@ -99,24 +98,24 @@ suite('ExtHostWorkspace', function () {
|
||||
});
|
||||
|
||||
test('getPath, legacy', function () {
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService());
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter());
|
||||
assert.equal(ws.getPath(), undefined);
|
||||
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService());
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter());
|
||||
assert.equal(ws.getPath(), undefined);
|
||||
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined, new NullLogService());
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined, new NullLogService(), new Counter());
|
||||
assert.equal(ws.getPath(), undefined);
|
||||
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService());
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter());
|
||||
assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder');
|
||||
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService());
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService(), new Counter());
|
||||
assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder');
|
||||
});
|
||||
|
||||
test('WorkspaceFolder has name and index', function () {
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter());
|
||||
|
||||
const [one, two] = ws.getWorkspaceFolders();
|
||||
|
||||
@@ -126,7 +125,7 @@ suite('ExtHostWorkspace', function () {
|
||||
assert.equal(two.index, 1);
|
||||
});
|
||||
|
||||
test('getContainingWorkspaceFolder', function () {
|
||||
test('getContainingWorkspaceFolder', () => {
|
||||
const ws = new ExtHostWorkspace(new TestRPCProtocol(), {
|
||||
id: 'foo',
|
||||
name: 'Test',
|
||||
@@ -135,7 +134,7 @@ suite('ExtHostWorkspace', function () {
|
||||
aWorkspaceFolderData(URI.file('/Coding/Two'), 1),
|
||||
aWorkspaceFolderData(URI.file('/Coding/Two/Nested'), 2)
|
||||
]
|
||||
}, new NullLogService());
|
||||
}, new NullLogService(), new Counter());
|
||||
|
||||
let folder = ws.getWorkspaceFolder(URI.file('/foo/bar'));
|
||||
assert.equal(folder, undefined);
|
||||
@@ -175,7 +174,7 @@ suite('ExtHostWorkspace', function () {
|
||||
});
|
||||
|
||||
test('Multiroot change event should have a delta, #29641', function (done) {
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService());
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter());
|
||||
|
||||
let finished = false;
|
||||
const finish = (error?: any) => {
|
||||
@@ -238,7 +237,7 @@ suite('ExtHostWorkspace', function () {
|
||||
});
|
||||
|
||||
test('Multiroot change keeps existing workspaces live', function () {
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService());
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter());
|
||||
|
||||
let firstFolder = ws.getWorkspaceFolders()[0];
|
||||
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar2'), 0), aWorkspaceFolderData(URI.parse('foo:bar'), 1, 'renamed')] });
|
||||
@@ -258,7 +257,7 @@ suite('ExtHostWorkspace', function () {
|
||||
});
|
||||
|
||||
test('updateWorkspaceFolders - invalid arguments', function () {
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService());
|
||||
let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter());
|
||||
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null, null));
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 0));
|
||||
@@ -267,7 +266,7 @@ suite('ExtHostWorkspace', function () {
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, 0));
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, -1));
|
||||
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService());
|
||||
ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter());
|
||||
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 1, 1));
|
||||
assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 2));
|
||||
@@ -276,20 +275,20 @@ suite('ExtHostWorkspace', function () {
|
||||
|
||||
test('updateWorkspaceFolders - valid arguments', function (done) {
|
||||
let finished = false;
|
||||
const finish = (error?) => {
|
||||
const finish = (error?: any) => {
|
||||
if (!finished) {
|
||||
finished = true;
|
||||
done(error);
|
||||
}
|
||||
};
|
||||
|
||||
const protocol = {
|
||||
const protocol: IMainContext = {
|
||||
getProxy: () => { return undefined; },
|
||||
set: undefined,
|
||||
assertRegistered: undefined
|
||||
};
|
||||
|
||||
const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService());
|
||||
const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter());
|
||||
|
||||
//
|
||||
// Add one folder
|
||||
@@ -512,7 +511,7 @@ suite('ExtHostWorkspace', function () {
|
||||
|
||||
finish();
|
||||
});
|
||||
|
||||
|
||||
// {{SQL CARBON EDIT}} remove broken test
|
||||
|
||||
test('`vscode.workspace.getWorkspaceFolder(file)` don\'t return workspace folder when file open from command line. #36221', function () {
|
||||
@@ -520,7 +519,7 @@ suite('ExtHostWorkspace', function () {
|
||||
id: 'foo', name: 'Test', folders: [
|
||||
aWorkspaceFolderData(URI.file('c:/Users/marek/Desktop/vsc_test/'), 0)
|
||||
]
|
||||
}, new NullLogService());
|
||||
}, new NullLogService(), new Counter());
|
||||
|
||||
assert.ok(ws.getWorkspaceFolder(URI.file('c:/Users/marek/Desktop/vsc_test/a.txt')));
|
||||
assert.ok(ws.getWorkspaceFolder(URI.file('C:/Users/marek/Desktop/vsc_test/b.txt')));
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MainThreadCommands } from 'vs/workbench/api/electron-browser/mainThreadCommands';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions, IConfigurationRegistry, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MarkerService } from 'vs/platform/markers/common/markerService';
|
||||
import { MainThreadDiagnostics } from 'vs/workbench/api/electron-browser/mainThreadDiagnostics';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
|
||||
suite('MainThreadDiagnostics', function () {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { MainThreadDocumentContentProviders } from 'vs/workbench/api/electron-browser/mainThreadDocumentContentProviders';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol';
|
||||
|
||||
suite('MainThreadDocumentContentProviders', function () {
|
||||
|
||||
test('events are processed properly', function () {
|
||||
|
||||
let uri = URI.parse('test:uri');
|
||||
let model = TextModel.createFromString('1', undefined, undefined, uri);
|
||||
|
||||
let providers = new MainThreadDocumentContentProviders(new TestRPCProtocol(), null, null,
|
||||
new class extends mock<IModelService>() {
|
||||
getModel(_uri) {
|
||||
assert.equal(uri.toString(), _uri.toString());
|
||||
return model;
|
||||
}
|
||||
},
|
||||
new class extends mock<IEditorWorkerService>() {
|
||||
computeMoreMinimalEdits(_uri, data) {
|
||||
assert.equal(model.getValue(), '1');
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let expectedEvents = 1;
|
||||
model.onDidChangeContent(e => {
|
||||
expectedEvents -= 1;
|
||||
try {
|
||||
assert.ok(expectedEvents >= 0);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
if (model.getValue() === '1\n2\n3') {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
providers.$onVirtualDocumentChange(uri, '1\n2');
|
||||
providers.$onVirtualDocumentChange(uri, '1\n2\n3');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { BoundModelReferenceCollection } from 'vs/workbench/api/electron-browser/mainThreadDocuments';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
@@ -18,7 +16,7 @@ suite('BoundModelReferenceCollection', () => {
|
||||
col.dispose();
|
||||
});
|
||||
|
||||
test('max age', () => {
|
||||
test('max age', async () => {
|
||||
|
||||
let didDispose = false;
|
||||
|
||||
@@ -29,9 +27,8 @@ suite('BoundModelReferenceCollection', () => {
|
||||
}
|
||||
});
|
||||
|
||||
return timeout(30).then(() => {
|
||||
assert.equal(didDispose, true);
|
||||
});
|
||||
await timeout(30);
|
||||
assert.equal(didDispose, true);
|
||||
});
|
||||
|
||||
test('max size', () => {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MainThreadDocumentsAndEditors } from 'vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors';
|
||||
import { SingleProxyRPCProtocol } from './testRPCProtocol';
|
||||
@@ -15,12 +13,13 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile
|
||||
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { createTestCodeEditor, TestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
import { TestEditorService, TestEditorGroupsService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestEditorService, TestEditorGroupsService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
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';
|
||||
|
||||
suite('MainThreadDocumentsAndEditors', () => {
|
||||
|
||||
@@ -43,7 +42,7 @@ suite('MainThreadDocumentsAndEditors', () => {
|
||||
deltas.length = 0;
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('editor', { 'detectIndentation': false });
|
||||
modelService = new ModelServiceImpl(null, configService);
|
||||
modelService = new ModelServiceImpl(null, configService, new TestTextResourcePropertiesService(configService));
|
||||
codeEditorService = new TestCodeEditorService();
|
||||
textFileService = new class extends mock<ITextFileService>() {
|
||||
isDirty() { return false; }
|
||||
@@ -74,7 +73,15 @@ suite('MainThreadDocumentsAndEditors', () => {
|
||||
null,
|
||||
null,
|
||||
editorGroupService,
|
||||
null
|
||||
null,
|
||||
new class extends mock<IPanelService>() implements IPanelService {
|
||||
_serviceBrand: any;
|
||||
onDidPanelOpen = Event.None;
|
||||
onDidPanelClose = Event.None;
|
||||
getActivePanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
/* tslint:enable */
|
||||
});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MainThreadDocumentsAndEditors } from 'vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors';
|
||||
import { SingleProxyRPCProtocol, TestRPCProtocol } from './testRPCProtocol';
|
||||
@@ -16,19 +14,19 @@ import { ExtHostDocumentsAndEditorsShape, ExtHostContext, ExtHostDocumentsShape
|
||||
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { MainThreadTextEditors } from 'vs/workbench/api/electron-browser/mainThreadEditors';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestContextService, TestTextResourcePropertiesService, TestWindowService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { ResourceTextEdit } from 'vs/editor/common/modes';
|
||||
import { BulkEditService } from 'vs/workbench/services/bulkEdit/electron-browser/bulkEditService';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import { IReference, ImmortalReference } from 'vs/base/common/lifecycle';
|
||||
import { UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay';
|
||||
import { LabelService } from 'vs/platform/label/common/label';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
|
||||
suite('MainThreadEditors', () => {
|
||||
|
||||
@@ -43,7 +41,7 @@ suite('MainThreadEditors', () => {
|
||||
|
||||
setup(() => {
|
||||
const configService = new TestConfigurationService();
|
||||
modelService = new ModelServiceImpl(null, configService);
|
||||
modelService = new ModelServiceImpl(null, configService, new TestTextResourcePropertiesService(configService));
|
||||
const codeEditorService = new TestCodeEditorService();
|
||||
|
||||
movedResources.clear();
|
||||
@@ -56,15 +54,15 @@ suite('MainThreadEditors', () => {
|
||||
isDirty() { return false; }
|
||||
create(uri: URI, contents?: string, options?: any) {
|
||||
createdResources.add(uri);
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
delete(resource: URI) {
|
||||
deletedResources.add(resource);
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
move(source: URI, target: URI) {
|
||||
movedResources.set(source, target);
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
models = <any>{
|
||||
onModelSaved: Event.None,
|
||||
@@ -75,15 +73,16 @@ suite('MainThreadEditors', () => {
|
||||
const workbenchEditorService = new TestEditorService();
|
||||
const editorGroupService = new TestEditorGroupsService();
|
||||
const textModelService = new class extends mock<ITextModelService>() {
|
||||
createModelReference(resource: URI): TPromise<IReference<ITextEditorModel>> {
|
||||
createModelReference(resource: URI): Promise<IReference<ITextEditorModel>> {
|
||||
const textEditorModel: ITextEditorModel = new class extends mock<ITextEditorModel>() {
|
||||
textEditorModel = modelService.getModel(resource);
|
||||
};
|
||||
return TPromise.as(new ImmortalReference(textEditorModel));
|
||||
textEditorModel.isReadonly = () => false;
|
||||
return Promise.resolve(new ImmortalReference(textEditorModel));
|
||||
}
|
||||
};
|
||||
|
||||
const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new UriDisplayService(TestEnvironmentService, new TestContextService()));
|
||||
const bulkEditService = new BulkEditService(new NullLogService(), modelService, new TestEditorService(), textModelService, new TestFileService(), textFileService, new LabelService(TestEnvironmentService, new TestContextService(), new TestWindowService()), configService);
|
||||
|
||||
const rpcProtocol = new TestRPCProtocol();
|
||||
rpcProtocol.set(ExtHostContext.ExtHostDocuments, new class extends mock<ExtHostDocumentsShape>() {
|
||||
@@ -107,6 +106,14 @@ suite('MainThreadEditors', () => {
|
||||
null,
|
||||
editorGroupService,
|
||||
bulkEditService,
|
||||
new class extends mock<IPanelService>() implements IPanelService {
|
||||
_serviceBrand: any;
|
||||
onDidPanelOpen = Event.None;
|
||||
onDidPanelClose = Event.None;
|
||||
getActivePanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
editors = new MainThreadTextEditors(
|
||||
@@ -169,7 +176,7 @@ suite('MainThreadEditors', () => {
|
||||
// second edit request fails
|
||||
assert.equal(result, false);
|
||||
});
|
||||
return TPromise.join([p1, p2]);
|
||||
return Promise.all([p1, p2]);
|
||||
});
|
||||
|
||||
test(`applyWorkspaceEdit with only resource edit`, () => {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { FinalNewLineParticipant, TrimFinalNewLinesParticipant } from 'vs/workbench/api/electron-browser/mainThreadSaveParticipant';
|
||||
@@ -39,131 +37,125 @@ suite('MainThreadSaveParticipant', function () {
|
||||
TextFileEditorModel.setSaveParticipant(null); // reset any set participant
|
||||
});
|
||||
|
||||
test('insert final new line', function () {
|
||||
test('insert final new line', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8');
|
||||
|
||||
return model.load().then(() => {
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'insertFinalNewline': true });
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'insertFinalNewline': true });
|
||||
const participant = new FinalNewLineParticipant(configService, undefined);
|
||||
|
||||
const participant = new FinalNewLineParticipant(configService, undefined);
|
||||
// No new line for empty lines
|
||||
let lineContent = '';
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
|
||||
// No new line for empty lines
|
||||
let lineContent = '';
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
// No new line if last line already empty
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
|
||||
// No new line if last line already empty
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
// New empty line added (single line)
|
||||
lineContent = 'Hello New Line';
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
|
||||
// New empty line added (single line)
|
||||
lineContent = 'Hello New Line';
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
|
||||
// New empty line added (multi line)
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
});
|
||||
// New empty line added (multi line)
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
});
|
||||
|
||||
test('trim final new lines', function () {
|
||||
test('trim final new lines', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
|
||||
return model.load().then(() => {
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
const textContent = 'Trim New Line';
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
// No new line removal if last line is not new line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
|
||||
const textContent = 'Trim New Line';
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
// No new line removal if last line is single new line
|
||||
lineContent = `${textContent}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
|
||||
// No new line removal if last line is not new line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
// Remove new line (single line with two new lines)
|
||||
lineContent = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
|
||||
// No new line removal if last line is single new line
|
||||
lineContent = `${textContent}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), lineContent);
|
||||
|
||||
// Remove new line (single line with two new lines)
|
||||
lineContent = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
|
||||
// Remove new lines (multiple lines with multiple new lines)
|
||||
lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}${textContent}${eol}`);
|
||||
});
|
||||
// Remove new lines (multiple lines with multiple new lines)
|
||||
lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}${textContent}${eol}`);
|
||||
});
|
||||
|
||||
test('trim final new lines bug#39750', function () {
|
||||
test('trim final new lines bug#39750', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
|
||||
return model.load().then(() => {
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
const textContent = 'Trim New Line';
|
||||
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
// single line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
|
||||
const textContent = 'Trim New Line';
|
||||
// apply edits and push to undo stack.
|
||||
let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }];
|
||||
model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
|
||||
|
||||
// single line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
// apply edits and push to undo stack.
|
||||
let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }];
|
||||
model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
|
||||
// undo
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}`);
|
||||
// trim final new lines should not mess the undo stack
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}.`);
|
||||
});
|
||||
// undo
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}`);
|
||||
|
||||
// trim final new lines should not mess the undo stack
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}.`);
|
||||
});
|
||||
|
||||
test('trim final new lines bug#46075', function () {
|
||||
test('trim final new lines bug#46075', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
|
||||
return model.load().then(() => {
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
const textContent = 'Test';
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
let content = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(content);
|
||||
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined);
|
||||
// save many times
|
||||
for (let i = 0; i < 10; i++) {
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
}
|
||||
|
||||
const textContent = 'Test';
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
// confirm trimming
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
|
||||
let content = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel.setValue(content);
|
||||
// save many times
|
||||
for (let i = 0; i < 10; i++) {
|
||||
participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
}
|
||||
// confirm trimming
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
// undo should go back to previous content immediately
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}${eol}`);
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
});
|
||||
// undo should go back to previous content immediately
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}${eol}`);
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()), `${textContent}${eol}`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export interface Ctor<T> {
|
||||
new(): T;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import { isThenable } from 'vs/base/common/async';
|
||||
|
||||
export function SingleProxyRPCProtocol(thing: any): IExtHostContext {
|
||||
return {
|
||||
remoteAuthority: null,
|
||||
getProxy<T>(): T {
|
||||
return thing;
|
||||
},
|
||||
@@ -22,10 +21,10 @@ export function SingleProxyRPCProtocol(thing: any): IExtHostContext {
|
||||
};
|
||||
}
|
||||
|
||||
declare var Proxy: any; // TODO@TypeScript
|
||||
|
||||
export class TestRPCProtocol implements IExtHostContext {
|
||||
|
||||
public remoteAuthority = null;
|
||||
|
||||
private _callCountValue: number = 0;
|
||||
private _idle: Promise<any>;
|
||||
private _completeIdle: Function;
|
||||
@@ -69,10 +68,10 @@ export class TestRPCProtocol implements IExtHostContext {
|
||||
}
|
||||
|
||||
public getProxy<T>(identifier: ProxyIdentifier<T>): T {
|
||||
if (!this._proxies[identifier.id]) {
|
||||
this._proxies[identifier.id] = this._createProxy(identifier.id);
|
||||
if (!this._proxies[identifier.sid]) {
|
||||
this._proxies[identifier.sid] = this._createProxy(identifier.sid);
|
||||
}
|
||||
return this._proxies[identifier.id];
|
||||
return this._proxies[identifier.sid];
|
||||
}
|
||||
|
||||
private _createProxy<T>(proxyId: string): T {
|
||||
@@ -90,14 +89,14 @@ export class TestRPCProtocol implements IExtHostContext {
|
||||
}
|
||||
|
||||
public set<T, R extends T>(identifier: ProxyIdentifier<T>, value: R): R {
|
||||
this._locals[identifier.id] = value;
|
||||
this._locals[identifier.sid] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
protected _remoteCall(proxyId: string, path: string, args: any[]): TPromise<any> {
|
||||
protected _remoteCall(proxyId: string, path: string, args: any[]): Promise<any> {
|
||||
this._callCount++;
|
||||
|
||||
return new TPromise<any>((c) => {
|
||||
return new Promise<any>((c) => {
|
||||
setTimeout(c, 0);
|
||||
}).then(() => {
|
||||
const instance = this._locals[proxyId];
|
||||
@@ -106,9 +105,9 @@ export class TestRPCProtocol implements IExtHostContext {
|
||||
let p: Thenable<any>;
|
||||
try {
|
||||
let result = (<Function>instance[path]).apply(instance, wireArgs);
|
||||
p = TPromise.is(result) ? result : TPromise.as(result);
|
||||
p = isThenable(result) ? result : Promise.resolve(result);
|
||||
} catch (err) {
|
||||
p = TPromise.wrapError(err);
|
||||
p = Promise.reject(err);
|
||||
}
|
||||
|
||||
return p.then(result => {
|
||||
@@ -118,7 +117,7 @@ export class TestRPCProtocol implements IExtHostContext {
|
||||
return wireResult;
|
||||
}, err => {
|
||||
this._callCount--;
|
||||
return TPromise.wrapError(err);
|
||||
return Promise.reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user