extHostLanguageFeatures.test.ts 38.6 KB
Newer Older
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import * as assert from 'assert';
9
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
J
Johannes Rieken 已提交
10
import { setUnexpectedErrorHandler, errorHandler } from 'vs/base/common/errors';
11
import URI from 'vs/base/common/uri';
J
Johannes Rieken 已提交
12
import * as types from 'vs/workbench/api/node/extHostTypes';
A
Alex Dima 已提交
13
import { TextModel as EditorModel } from 'vs/editor/common/model/textModel';
J
Johannes Rieken 已提交
14 15
import { Position as EditorPosition } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
A
Alex Dima 已提交
16
import { TestRPCProtocol } from './testRPCProtocol';
J
Johannes Rieken 已提交
17
import { IMarkerService } from 'vs/platform/markers/common/markers';
18
import { MarkerService } from 'vs/platform/markers/common/markerService';
J
Johannes Rieken 已提交
19
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
20
import { MainThreadLanguageFeatures } from 'vs/workbench/api/electron-browser/mainThreadLanguageFeatures';
J
Johannes Rieken 已提交
21
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
22 23
import { MainThreadCommands } from 'vs/workbench/api/electron-browser/mainThreadCommands';
import { IHeapService } from 'vs/workbench/api/electron-browser/mainThreadHeapService';
J
Johannes Rieken 已提交
24
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
J
Johannes Rieken 已提交
25
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
26
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/quickOpen';
27
import { DocumentSymbolProviderRegistry, DocumentHighlightKind, Hover, ResourceTextEdit } from 'vs/editor/common/modes';
28 29 30 31 32
import { getCodeLensData } from 'vs/editor/contrib/codelens/codelens';
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDeclaration/goToDeclaration';
import { getHover } from 'vs/editor/contrib/hover/getHover';
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/wordHighlighter';
import { provideReferences } from 'vs/editor/contrib/referenceSearch/referenceSearch';
33
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
J
Johannes Rieken 已提交
34
import { getWorkspaceSymbols } from 'vs/workbench/parts/search/common/search';
35 36 37 38 39
import { rename } from 'vs/editor/contrib/rename/rename';
import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/provideSignatureHelp';
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';
J
Johannes Rieken 已提交
40 41 42 43
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';
44
import * as vscode from 'vscode';
B
Benjamin Pasero 已提交
45
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
46
import { NullLogService } from 'vs/platform/log/common/log';
A
Alex Dima 已提交
47
import { ITextModel, EndOfLineSequence } from 'vs/editor/common/model';
48
import { getColors } from 'vs/editor/contrib/colorPicker/color';
49 50

const defaultSelector = { scheme: 'far' };
A
Alex Dima 已提交
51
const model: ITextModel = EditorModel.createFromString(
52 53 54 55 56
	[
		'This is the first line',
		'This is the second line',
		'This is the third line',
	].join('\n'),
57
	undefined,
58
	undefined,
J
Johannes Rieken 已提交
59
	URI.parse('far://testing/file.a'));
60 61 62 63

let extHost: ExtHostLanguageFeatures;
let mainThread: MainThreadLanguageFeatures;
let disposables: vscode.Disposable[] = [];
A
Alex Dima 已提交
64
let rpcProtocol: TestRPCProtocol;
65 66
let originalErrorHandler: (e: any) => any;

J
Johannes Rieken 已提交
67
suite('ExtHostLanguageFeatures', function () {
68 69 70

	suiteSetup(() => {

A
Alex Dima 已提交
71
		rpcProtocol = new TestRPCProtocol();
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

		// Use IInstantiationService to get typechecking when instantiating
		let inst: IInstantiationService;
		{
			let instantiationService = new TestInstantiationService();
			instantiationService.stub(IMarkerService, MarkerService);
			instantiationService.stub(IHeapService, {
				_serviceBrand: undefined,
				trackRecursive(args) {
					// nothing
					return args;
				}
			});
			inst = instantiationService;
		}
J
Johannes Rieken 已提交
87

88 89 90
		originalErrorHandler = errorHandler.getUnexpectedErrorHandler();
		setUnexpectedErrorHandler(() => { });

A
Alex Dima 已提交
91
		const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol);
J
Johannes Rieken 已提交
92 93 94 95 96
		extHostDocumentsAndEditors.$acceptDocumentsAndEditorsDelta({
			addedDocuments: [{
				isDirty: false,
				versionId: model.getVersionId(),
				modeId: model.getLanguageIdentifier().language,
97
				uri: model.uri,
J
Johannes Rieken 已提交
98 99 100
				lines: model.getValue().split(model.getEOL()),
				EOL: model.getEOL(),
			}]
101
		});
A
Alex Dima 已提交
102 103
		const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors);
		rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments);
104

105 106
		const heapService = new ExtHostHeapService();

A
Alex Dima 已提交
107 108 109
		const commands = new ExtHostCommands(rpcProtocol, heapService, new NullLogService());
		rpcProtocol.set(ExtHostContext.ExtHostCommands, commands);
		rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol));
110

A
Alex Dima 已提交
111 112
		const diagnostics = new ExtHostDiagnostics(rpcProtocol);
		rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, diagnostics);
113

A
Alex Dima 已提交
114
		extHost = new ExtHostLanguageFeatures(rpcProtocol, null, extHostDocuments, commands, heapService, diagnostics);
A
Alex Dima 已提交
115
		rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, extHost);
116

A
Alex Dima 已提交
117
		mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, rpcProtocol));
118 119 120 121
	});

	suiteTeardown(() => {
		setUnexpectedErrorHandler(originalErrorHandler);
122
		model.dispose();
J
Johannes Rieken 已提交
123
		mainThread.dispose();
124 125
	});

J
Johannes Rieken 已提交
126
	teardown(function () {
127 128 129
		while (disposables.length) {
			disposables.pop().dispose();
		}
A
Alex Dima 已提交
130
		return rpcProtocol.sync();
131 132
	});

133 134
	// --- outline

J
Johannes Rieken 已提交
135
	test('DocumentSymbols, register/deregister', function () {
136
		assert.equal(DocumentSymbolProviderRegistry.all(model).length, 0);
137
		let d1 = extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
138 139 140 141 142
			provideDocumentSymbols() {
				return [];
			}
		});

A
Alex Dima 已提交
143
		return rpcProtocol.sync().then(() => {
144
			assert.equal(DocumentSymbolProviderRegistry.all(model).length, 1);
145
			d1.dispose();
A
Alex Dima 已提交
146
			return rpcProtocol.sync();
147 148 149 150
		});

	});

J
Johannes Rieken 已提交
151
	test('DocumentSymbols, evil provider', function () {
152
		disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
153 154 155 156
			provideDocumentSymbols(): any {
				throw new Error('evil document symbol provider');
			}
		}));
157
		disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
158
			provideDocumentSymbols(): any {
159
				return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))];
160 161 162
			}
		}));

A
Alex Dima 已提交
163
		return rpcProtocol.sync().then(() => {
164

165
			return getDocumentSymbols(model).then(value => {
166 167 168 169 170
				assert.equal(value.entries.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
171
	test('DocumentSymbols, data conversion', function () {
172
		disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, <vscode.DocumentSymbolProvider>{
173
			provideDocumentSymbols(): any {
174
				return [new types.SymbolInformation('test', types.SymbolKind.Field, new types.Range(0, 0, 0, 0))];
175 176 177
			}
		}));

A
Alex Dima 已提交
178
		return rpcProtocol.sync().then(() => {
179

180
			return getDocumentSymbols(model).then(value => {
181 182 183
				assert.equal(value.entries.length, 1);

				let entry = value.entries[0];
184 185
				assert.equal(entry.name, 'test');
				assert.deepEqual(entry.location.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
186 187 188
			});
		});
	});
189 190 191

	// --- code lens

J
Johannes Rieken 已提交
192
	test('CodeLens, evil provider', function () {
193

194
		disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
J
tslint  
Johannes Rieken 已提交
195
			provideCodeLenses(): any {
B
Benjamin Pasero 已提交
196
				throw new Error('evil');
197 198
			}
		}));
199
		disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
200 201 202 203 204
			provideCodeLenses() {
				return [new types.CodeLens(new types.Range(0, 0, 0, 0))];
			}
		}));

A
Alex Dima 已提交
205
		return rpcProtocol.sync().then(() => {
206
			return getCodeLensData(model).then(value => {
207 208 209 210 211
				assert.equal(value.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
212
	test('CodeLens, do not resolve a resolved lens', function () {
213

214
		disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
J
tslint  
Johannes Rieken 已提交
215
			provideCodeLenses(): any {
216 217 218 219
				return [new types.CodeLens(
					new types.Range(0, 0, 0, 0),
					{ command: 'id', title: 'Title' })];
			},
J
tslint  
Johannes Rieken 已提交
220
			resolveCodeLens(): any {
221 222 223 224
				assert.ok(false, 'do not resolve');
			}
		}));

A
Alex Dima 已提交
225
		return rpcProtocol.sync().then(() => {
226

227
			return getCodeLensData(model).then(value => {
228 229 230
				assert.equal(value.length, 1);
				let data = value[0];

231
				return asWinJsPromise((token) => {
232
					return data.provider.resolveCodeLens(model, data.symbol, token);
233
				}).then(symbol => {
J
Johannes Rieken 已提交
234 235
					assert.equal(symbol.command.id, 'id');
					assert.equal(symbol.command.title, 'Title');
236 237 238 239 240
				});
			});
		});
	});

J
Johannes Rieken 已提交
241
	test('CodeLens, missing command', function () {
242

243
		disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
244 245 246 247 248
			provideCodeLenses() {
				return [new types.CodeLens(new types.Range(0, 0, 0, 0))];
			}
		}));

A
Alex Dima 已提交
249
		return rpcProtocol.sync().then(() => {
250

251
			return getCodeLensData(model).then(value => {
252 253 254
				assert.equal(value.length, 1);

				let data = value[0];
255
				return asWinJsPromise((token) => {
256
					return data.provider.resolveCodeLens(model, data.symbol, token);
257
				}).then(symbol => {
258

J
Johannes Rieken 已提交
259 260
					assert.equal(symbol.command.id, 'missing');
					assert.equal(symbol.command.title, '<<MISSING COMMAND>>');
261 262 263 264
				});
			});
		});
	});
J
Johannes Rieken 已提交
265 266 267

	// --- definition

J
Johannes Rieken 已提交
268
	test('Definition, data conversion', function () {
J
Johannes Rieken 已提交
269

270
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
271
			provideDefinition(): any {
272
				return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
J
Johannes Rieken 已提交
273 274 275
			}
		}));

A
Alex Dima 已提交
276
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
277

278
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
279 280 281
				assert.equal(value.length, 1);
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
282
				assert.equal(entry.uri.toString(), model.uri.toString());
J
Johannes Rieken 已提交
283 284 285 286
			});
		});
	});

J
Johannes Rieken 已提交
287
	test('Definition, one or many', function () {
J
Johannes Rieken 已提交
288

289
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
290
			provideDefinition(): any {
291
				return [new types.Location(model.uri, new types.Range(1, 1, 1, 1))];
J
Johannes Rieken 已提交
292 293
			}
		}));
294
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
295
			provideDefinition(): any {
296
				return new types.Location(model.uri, new types.Range(1, 1, 1, 1));
J
Johannes Rieken 已提交
297 298 299
			}
		}));

A
Alex Dima 已提交
300
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
301

302
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
303 304 305 306 307
				assert.equal(value.length, 2);
			});
		});
	});

308
	test('Definition, registration order', function () {
J
Johannes Rieken 已提交
309

310
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
311 312 313 314 315
			provideDefinition(): any {
				return [new types.Location(URI.parse('far://first'), new types.Range(2, 3, 4, 5))];
			}
		}));

316 317 318 319 320
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
			provideDefinition(): any {
				return new types.Location(URI.parse('far://second'), new types.Range(1, 2, 3, 4));
			}
		}));
J
Johannes Rieken 已提交
321

A
Alex Dima 已提交
322
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
323

324
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
325 326
				assert.equal(value.length, 2);
				// let [first, second] = value;
J
Johannes Rieken 已提交
327

328 329
				assert.equal(value[0].uri.authority, 'second');
				assert.equal(value[1].uri.authority, 'first');
J
Johannes Rieken 已提交
330
			});
331
		});
J
Johannes Rieken 已提交
332 333
	});

J
Johannes Rieken 已提交
334
	test('Definition, evil provider', function () {
J
Johannes Rieken 已提交
335

336
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
337
			provideDefinition(): any {
B
Benjamin Pasero 已提交
338
				throw new Error('evil provider');
J
Johannes Rieken 已提交
339 340
			}
		}));
341
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
342
			provideDefinition(): any {
343
				return new types.Location(model.uri, new types.Range(1, 1, 1, 1));
J
Johannes Rieken 已提交
344 345 346
			}
		}));

A
Alex Dima 已提交
347
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
348

349
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
350 351 352 353
				assert.equal(value.length, 1);
			});
		});
	});
J
Johannes Rieken 已提交
354

355
	// --- implementation
356

M
Matt Bierner 已提交
357
	test('Implementation, data conversion', function () {
358

M
Matt Bierner 已提交
359 360
		disposables.push(extHost.registerImplementationProvider(defaultSelector, <vscode.ImplementationProvider>{
			provideImplementation(): any {
361 362 363 364
				return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
			}
		}));

A
Alex Dima 已提交
365
		return rpcProtocol.sync().then(() => {
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
			return getImplementationsAtPosition(model, new EditorPosition(1, 1)).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());
			});
		});
	});

	// --- type definition

	test('Type Definition, data conversion', function () {

		disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
			provideTypeDefinition(): any {
				return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
			}
		}));

A
Alex Dima 已提交
385
		return rpcProtocol.sync().then(() => {
386
			return getTypeDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
387 388 389 390 391 392 393 394
				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());
			});
		});
	});

J
Johannes Rieken 已提交
395 396
	// --- extra info

J
Johannes Rieken 已提交
397
	test('HoverProvider, word range at pos', function () {
J
Johannes Rieken 已提交
398

399
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
400
			provideHover(): any {
B
Benjamin Pasero 已提交
401
				return new types.Hover('Hello');
J
Johannes Rieken 已提交
402 403 404
			}
		}));

A
Alex Dima 已提交
405
		return rpcProtocol.sync().then(() => {
406
			getHover(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
407 408 409 410 411 412 413
				assert.equal(value.length, 1);
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 });
			});
		});
	});

414

J
Johannes Rieken 已提交
415
	test('HoverProvider, given range', function () {
J
Johannes Rieken 已提交
416

417
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
418 419 420 421 422
			provideHover(): any {
				return new types.Hover('Hello', new types.Range(3, 0, 8, 7));
			}
		}));

A
Alex Dima 已提交
423
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
424

425
			getHover(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
426 427 428 429 430 431 432 433
				assert.equal(value.length, 1);
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 4, startColumn: 1, endLineNumber: 9, endColumn: 8 });
			});
		});
	});


434
	test('HoverProvider, registration order', function () {
435
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
436 437 438 439 440 441
			provideHover(): any {
				return new types.Hover('registered first');
			}
		}));


442 443 444 445 446
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
			provideHover(): any {
				return new types.Hover('registered second');
			}
		}));
J
Johannes Rieken 已提交
447

A
Alex Dima 已提交
448
		return rpcProtocol.sync().then(() => {
449
			return getHover(model, new EditorPosition(1, 1)).then(value => {
450
				assert.equal(value.length, 2);
451
				let [first, second] = value as Hover[];
452 453
				assert.equal(first.contents[0].value, 'registered second');
				assert.equal(second.contents[0].value, 'registered first');
J
Johannes Rieken 已提交
454
			});
455
		});
J
Johannes Rieken 已提交
456 457
	});

458

J
Johannes Rieken 已提交
459
	test('HoverProvider, evil provider', function () {
J
Johannes Rieken 已提交
460

461
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
462
			provideHover(): any {
B
Benjamin Pasero 已提交
463
				throw new Error('evil');
J
Johannes Rieken 已提交
464 465
			}
		}));
466
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
467
			provideHover(): any {
B
Benjamin Pasero 已提交
468
				return new types.Hover('Hello');
J
Johannes Rieken 已提交
469 470 471
			}
		}));

A
Alex Dima 已提交
472
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
473

474
			getHover(model, new EditorPosition(1, 1)).then(value => {
475 476 477 478 479 480 481 482

				assert.equal(value.length, 1);
			});
		});
	});

	// --- occurrences

J
Johannes Rieken 已提交
483
	test('Occurrences, data conversion', function () {
484 485 486

		disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
487
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
488 489 490
			}
		}));

A
Alex Dima 已提交
491
		return rpcProtocol.sync().then(() => {
492

493
			return getOccurrencesAtPosition(model, new EditorPosition(1, 2)).then(value => {
494 495 496
				assert.equal(value.length, 1);
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 });
497
				assert.equal(entry.kind, DocumentHighlightKind.Text);
498 499 500 501
			});
		});
	});

J
Johannes Rieken 已提交
502
	test('Occurrences, order 1/2', function () {
503 504 505

		disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
506
				return [];
507 508 509 510
			}
		}));
		disposables.push(extHost.registerDocumentHighlightProvider('*', <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
511
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
512 513 514
			}
		}));

A
Alex Dima 已提交
515
		return rpcProtocol.sync().then(() => {
516

517
			return getOccurrencesAtPosition(model, new EditorPosition(1, 2)).then(value => {
518 519 520
				assert.equal(value.length, 1);
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 5 });
521
				assert.equal(entry.kind, DocumentHighlightKind.Text);
522 523 524 525
			});
		});
	});

J
Johannes Rieken 已提交
526
	test('Occurrences, order 2/2', function () {
527 528 529

		disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
530
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 2))];
531 532 533 534
			}
		}));
		disposables.push(extHost.registerDocumentHighlightProvider('*', <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
535
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
536 537 538
			}
		}));

A
Alex Dima 已提交
539
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
540

541
			return getOccurrencesAtPosition(model, new EditorPosition(1, 2)).then(value => {
J
Johannes Rieken 已提交
542
				assert.equal(value.length, 1);
543 544
				let [entry] = value;
				assert.deepEqual(entry.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 3 });
545
				assert.equal(entry.kind, DocumentHighlightKind.Text);
J
Johannes Rieken 已提交
546 547
			});
		});
548 549
	});

J
Johannes Rieken 已提交
550
	test('Occurrences, evil provider', function () {
551 552 553 554 555 556 557 558 559

		disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
				throw new Error('evil');
			}
		}));

		disposables.push(extHost.registerDocumentHighlightProvider(defaultSelector, <vscode.DocumentHighlightProvider>{
			provideDocumentHighlights(): any {
B
Benjamin Pasero 已提交
560
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
561 562 563
			}
		}));

A
Alex Dima 已提交
564
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
565

566
			return getOccurrencesAtPosition(model, new EditorPosition(1, 2)).then(value => {
567 568 569
				assert.equal(value.length, 1);
			});
		});
J
Johannes Rieken 已提交
570
	});
J
Johannes Rieken 已提交
571 572 573

	// --- references

574
	test('References, registration order', function () {
J
Johannes Rieken 已提交
575 576 577 578 579 580 581

		disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
			provideReferences(): any {
				return [new types.Location(URI.parse('far://register/first'), new types.Range(0, 0, 0, 0))];
			}
		}));

582 583 584 585 586
		disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
			provideReferences(): any {
				return [new types.Location(URI.parse('far://register/second'), new types.Range(0, 0, 0, 0))];
			}
		}));
J
Johannes Rieken 已提交
587

A
Alex Dima 已提交
588
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
589

590
			return provideReferences(model, new EditorPosition(1, 2)).then(value => {
591
				assert.equal(value.length, 2);
J
Johannes Rieken 已提交
592

593
				let [first, second] = value;
594 595
				assert.equal(first.uri.path, '/second');
				assert.equal(second.uri.path, '/first');
J
Johannes Rieken 已提交
596
			});
597
		});
J
Johannes Rieken 已提交
598 599
	});

J
Johannes Rieken 已提交
600
	test('References, data conversion', function () {
J
Johannes Rieken 已提交
601 602 603

		disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
			provideReferences(): any {
604
				return [new types.Location(model.uri, new types.Position(0, 0))];
J
Johannes Rieken 已提交
605 606 607
			}
		}));

A
Alex Dima 已提交
608
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
609

610
			return provideReferences(model, new EditorPosition(1, 2)).then(value => {
J
Johannes Rieken 已提交
611 612 613 614
				assert.equal(value.length, 1);

				let [item] = value;
				assert.deepEqual(item.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
615
				assert.equal(item.uri.toString(), model.uri.toString());
J
Johannes Rieken 已提交
616 617 618 619 620
			});

		});
	});

J
Johannes Rieken 已提交
621
	test('References, evil provider', function () {
J
Johannes Rieken 已提交
622 623 624 625 626 627 628 629

		disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
			provideReferences(): any {
				throw new Error('evil');
			}
		}));
		disposables.push(extHost.registerReferenceProvider(defaultSelector, <vscode.ReferenceProvider>{
			provideReferences(): any {
630
				return [new types.Location(model.uri, new types.Range(0, 0, 0, 0))];
J
Johannes Rieken 已提交
631 632 633
			}
		}));

A
Alex Dima 已提交
634
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
635

636
			return provideReferences(model, new EditorPosition(1, 2)).then(value => {
J
Johannes Rieken 已提交
637 638 639 640 641
				assert.equal(value.length, 1);
			});

		});
	});
J
Johannes Rieken 已提交
642 643 644

	// --- quick fix

M
Matt Bierner 已提交
645
	test('Quick Fix, command data conversion', function () {
J
Johannes Rieken 已提交
646

647 648
		disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
			provideCodeActions(): vscode.Command[] {
J
Johannes Rieken 已提交
649
				return [
650 651
					{ command: 'test1', title: 'Testing1' },
					{ command: 'test2', title: 'Testing2' }
J
Johannes Rieken 已提交
652 653 654 655
				];
			}
		}));

A
Alex Dima 已提交
656
		return rpcProtocol.sync().then(() => {
657
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
658 659
				assert.equal(value.length, 2);

660
				const [first, second] = value;
J
Johannes Rieken 已提交
661
				assert.equal(first.title, 'Testing1');
662
				assert.equal(first.command.id, 'test1');
J
Johannes Rieken 已提交
663
				assert.equal(second.title, 'Testing2');
664
				assert.equal(second.command.id, 'test2');
J
Johannes Rieken 已提交
665 666 667 668
			});
		});
	});

M
Matt Bierner 已提交
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
	test('Quick Fix, code action data conversion', function () {

		disposables.push(extHost.registerCodeActionProvider(defaultSelector, {
			provideCodeActions(): vscode.CodeAction[] {
				return [
					{
						title: 'Testing1',
						command: { title: 'Testing1Command', command: 'test1' },
						kind: types.CodeActionKind.Empty.append('test.scope')
					}
				];
			}
		}));

		return rpcProtocol.sync().then(() => {
			return getCodeActions(model, model.getFullModelRange()).then(value => {
				assert.equal(value.length, 1);

				const [first] = value;
				assert.equal(first.title, 'Testing1');
				assert.equal(first.command.title, 'Testing1Command');
				assert.equal(first.command.id, 'test1');
				assert.equal(first.kind, 'test.scope');
			});
		});
	});


J
Johannes Rieken 已提交
697 698 699 700 701 702 703 704 705 706 707 708
	test('Cannot read property \'id\' of undefined, #29469', function () {

		disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
			provideCodeActions(): any {
				return [
					undefined,
					null,
					<vscode.Command>{ command: 'test', title: 'Testing' }
				];
			}
		}));

A
Alex Dima 已提交
709
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
710 711
			return getCodeActions(model, model.getFullModelRange()).then(value => {
				assert.equal(value.length, 1);
J
Johannes Rieken 已提交
712 713 714 715
			});
		});
	});

J
Johannes Rieken 已提交
716
	test('Quick Fix, evil provider', function () {
J
Johannes Rieken 已提交
717 718 719 720 721 722 723 724 725 726 727 728

		disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
			provideCodeActions(): any {
				throw new Error('evil');
			}
		}));
		disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
			provideCodeActions(): any {
				return [<vscode.Command>{ command: 'test', title: 'Testing' }];
			}
		}));

A
Alex Dima 已提交
729
		return rpcProtocol.sync().then(() => {
730
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
731 732 733 734
				assert.equal(value.length, 1);
			});
		});
	});
735 736 737

	// --- navigate types

J
Johannes Rieken 已提交
738
	test('Navigate types, evil provider', function () {
739 740 741 742 743 744 745 746 747

		disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
			provideWorkspaceSymbols(): any {
				throw new Error('evil');
			}
		}));

		disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
			provideWorkspaceSymbols(): any {
B
Benjamin Pasero 已提交
748
				return [new types.SymbolInformation('testing', types.SymbolKind.Array, new types.Range(0, 0, 1, 1))];
749 750 751
			}
		}));

A
Alex Dima 已提交
752
		return rpcProtocol.sync().then(() => {
753

754
			return getWorkspaceSymbols('').then(value => {
755
				assert.equal(value.length, 1);
756 757 758 759
				const [first] = value;
				const [, symbols] = first;
				assert.equal(symbols.length, 1);
				assert.equal(symbols[0].name, 'testing');
760 761
			});
		});
J
Johannes Rieken 已提交
762 763 764 765
	});

	// --- rename

J
Johannes Rieken 已提交
766
	test('Rename, evil provider 0/2', function () {
J
Johannes Rieken 已提交
767 768 769

		disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
			provideRenameEdits(): any {
J
Johannes Rieken 已提交
770
				throw new class Foo { };
J
Johannes Rieken 已提交
771 772 773
			}
		}));

A
Alex Dima 已提交
774
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
775

776
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
777
				throw Error();
J
Johannes Rieken 已提交
778
			}, err => {
779
				// expected
J
Johannes Rieken 已提交
780 781 782 783
			});
		});
	});

J
Johannes Rieken 已提交
784 785 786 787 788 789 790 791
	test('Rename, evil provider 1/2', function () {

		disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
			provideRenameEdits(): any {
				throw Error('evil');
			}
		}));

A
Alex Dima 已提交
792
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
793 794 795 796 797 798 799

			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
				assert.equal(value.rejectReason, 'evil');
			});
		});
	});

J
Johannes Rieken 已提交
800
	test('Rename, evil provider 2/2', function () {
J
Johannes Rieken 已提交
801 802 803 804 805 806 807 808 809 810

		disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
			provideRenameEdits(): any {
				throw Error('evil');
			}
		}));

		disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
			provideRenameEdits(): any {
				let edit = new types.WorkspaceEdit();
811
				edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
J
Johannes Rieken 已提交
812 813 814 815
				return edit;
			}
		}));

A
Alex Dima 已提交
816
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
817

818
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
819 820 821 822 823
				assert.equal(value.edits.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
824
	test('Rename, ordering', function () {
J
Johannes Rieken 已提交
825 826 827 828

		disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
			provideRenameEdits(): any {
				let edit = new types.WorkspaceEdit();
829 830
				edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
				edit.replace(model.uri, new types.Range(1, 0, 1, 0), 'testing');
J
Johannes Rieken 已提交
831 832 833 834 835 836 837 838 839 840
				return edit;
			}
		}));

		disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
			provideRenameEdits(): any {
				return;
			}
		}));

A
Alex Dima 已提交
841
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
842

843
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
844 845
				assert.equal(value.edits.length, 1); // least relevant renamer
				assert.equal((<ResourceTextEdit[]>value.edits)[0].edits.length, 2); // least relevant renamer
J
Johannes Rieken 已提交
846 847 848
			});
		});
	});
849 850 851

	// --- parameter hints

J
Johannes Rieken 已提交
852 853 854 855 856 857 858 859 860 861
	test('Parameter Hints, order', function () {

		disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
			provideSignatureHelp(): any {
				return undefined;
			}
		}, []));

		disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
			provideSignatureHelp(): vscode.SignatureHelp {
862 863 864 865 866
				return {
					signatures: [],
					activeParameter: 0,
					activeSignature: 0
				};
J
Johannes Rieken 已提交
867 868 869
			}
		}, []));

A
Alex Dima 已提交
870
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
871 872 873 874 875 876

			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
				assert.ok(value);
			});
		});
	});
J
Johannes Rieken 已提交
877
	test('Parameter Hints, evil provider', function () {
878 879 880 881 882 883 884

		disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
			provideSignatureHelp(): any {
				throw new Error('evil');
			}
		}, []));

A
Alex Dima 已提交
885
		return rpcProtocol.sync().then(() => {
886

887
			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
888
				assert.equal(value, undefined);
B
Benjamin Pasero 已提交
889
			});
890
		});
891 892 893 894
	});

	// --- suggestions

J
Johannes Rieken 已提交
895
	test('Suggest, order 1/3', function () {
896 897 898 899 900 901 902 903 904 905 906 907 908

		disposables.push(extHost.registerCompletionItemProvider('*', <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('testing1')];
			}
		}, []));

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('testing2')];
			}
		}, []));

A
Alex Dima 已提交
909
		return rpcProtocol.sync().then(() => {
910
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
911
				assert.equal(value.length, 1);
912
				assert.equal(value[0].suggestion.insertText, 'testing2');
913 914 915 916
			});
		});
	});

J
Johannes Rieken 已提交
917
	test('Suggest, order 2/3', function () {
918 919 920 921 922 923 924 925 926 927 928 929 930

		disposables.push(extHost.registerCompletionItemProvider('*', <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('weak-selector')]; // weaker selector but result
			}
		}, []));

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return []; // stronger selector but not a good result;
			}
		}, []));

A
Alex Dima 已提交
931
		return rpcProtocol.sync().then(() => {
932
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
933
				assert.equal(value.length, 1);
934
				assert.equal(value[0].suggestion.insertText, 'weak-selector');
935 936
			});
		});
B
Benjamin Pasero 已提交
937
	});
938

939
	test('Suggest, order 2/3', function () {
940 941 942 943 944 945 946

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('strong-1')];
			}
		}, []));

947 948 949 950 951 952
		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('strong-2')];
			}
		}, []));

A
Alex Dima 已提交
953
		return rpcProtocol.sync().then(() => {
954
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
955
				assert.equal(value.length, 2);
956 957
				assert.equal(value[0].suggestion.insertText, 'strong-1'); // sort by label
				assert.equal(value[1].suggestion.insertText, 'strong-2');
958
			});
959
		});
B
Benjamin Pasero 已提交
960
	});
961

J
Johannes Rieken 已提交
962
	test('Suggest, evil provider', function () {
963 964 965 966 967 968 969 970 971 972 973 974 975 976

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				throw new Error('evil');
			}
		}, []));

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('testing')];
			}
		}, []));


A
Alex Dima 已提交
977
		return rpcProtocol.sync().then(() => {
978

979
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
980
				assert.equal(value[0].container.incomplete, undefined);
981 982 983
			});
		});
	});
984

J
Johannes Rieken 已提交
985
	test('Suggest, CompletionList', function () {
986 987 988

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
J
Johannes Rieken 已提交
989
				return new types.CompletionList([<any>new types.CompletionItem('hello')], true);
990 991 992
			}
		}, []));

A
Alex Dima 已提交
993
		return rpcProtocol.sync().then(() => {
994

995
			provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
996
				assert.equal(value[0].container.incomplete, true);
997 998 999 1000
			});
		});
	});

1001 1002
	// --- format

J
Johannes Rieken 已提交
1003
	test('Format Doc, data conversion', function () {
1004 1005
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
1006
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing'), types.TextEdit.setEndOfLine(types.EndOfLine.LF)];
1007 1008 1009
			}
		}));

A
Alex Dima 已提交
1010
		return rpcProtocol.sync().then(() => {
1011
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
1012 1013
				assert.equal(value.length, 2);
				let [first, second] = value;
1014
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
1015
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
1016

1017
				assert.equal(second.eol, EndOfLineSequence.LF);
1018 1019
				assert.equal(second.text, '');
				assert.equal(second.range, undefined);
1020 1021 1022 1023
			});
		});
	});

J
Johannes Rieken 已提交
1024
	test('Format Doc, evil provider', function () {
1025 1026 1027 1028 1029 1030
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

A
Alex Dima 已提交
1031
		return rpcProtocol.sync().then(() => {
1032 1033 1034 1035 1036
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 });
		});
	});

	test('Format Doc, order', function () {
1037 1038 1039 1040 1041 1042 1043

		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				return undefined;
			}
		}));

1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
			}
		}));

		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				return undefined;
			}
		}));

A
Alex Dima 已提交
1056
		return rpcProtocol.sync().then(() => {
1057 1058 1059 1060 1061 1062
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'testing');
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
			});
1063 1064 1065
		});
	});

J
Johannes Rieken 已提交
1066
	test('Format Range, data conversion', function () {
1067 1068
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1069
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
1070 1071 1072
			}
		}));

A
Alex Dima 已提交
1073
		return rpcProtocol.sync().then(() => {
1074
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1075 1076 1077
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
1078
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
1079 1080
			});
		});
B
Benjamin Pasero 已提交
1081
	});
1082

J
Johannes Rieken 已提交
1083
	test('Format Range, + format_doc', function () {
1084 1085
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1086
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'range')];
1087 1088
			}
		}));
1089 1090 1091 1092 1093
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
				return [new types.TextEdit(new types.Range(2, 3, 4, 5), 'range2')];
			}
		}));
1094 1095 1096 1097 1098
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				return [new types.TextEdit(new types.Range(0, 0, 1, 1), 'doc')];
			}
		}));
A
Alex Dima 已提交
1099
		return rpcProtocol.sync().then(() => {
1100
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1101 1102
				assert.equal(value.length, 1);
				let [first] = value;
1103 1104 1105 1106 1107
				assert.equal(first.text, 'range2');
				assert.equal(first.range.startLineNumber, 3);
				assert.equal(first.range.startColumn, 4);
				assert.equal(first.range.endLineNumber, 5);
				assert.equal(first.range.endColumn, 6);
1108 1109 1110 1111
			});
		});
	});

J
Johannes Rieken 已提交
1112
	test('Format Range, evil provider', function () {
1113 1114 1115 1116 1117 1118
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

A
Alex Dima 已提交
1119
		return rpcProtocol.sync().then(() => {
1120
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 });
1121
		});
B
Benjamin Pasero 已提交
1122
	});
1123

J
Johannes Rieken 已提交
1124
	test('Format on Type, data conversion', function () {
1125 1126 1127 1128 1129 1130 1131

		disposables.push(extHost.registerOnTypeFormattingEditProvider(defaultSelector, <vscode.OnTypeFormattingEditProvider>{
			provideOnTypeFormattingEdits(): any {
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), arguments[2])];
			}
		}, [';']));

A
Alex Dima 已提交
1132
		return rpcProtocol.sync().then(() => {
1133
			return getOnTypeFormattingEdits(model, new EditorPosition(1, 1), ';', { insertSpaces: true, tabSize: 2 }).then(value => {
1134 1135 1136 1137 1138 1139 1140 1141
				assert.equal(value.length, 1);
				let [first] = value;

				assert.equal(first.text, ';');
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
			});
		});
	});
J
Johannes Rieken 已提交
1142 1143 1144 1145 1146

	test('Links, data conversion', function () {

		disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
			provideDocumentLinks() {
1147
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1148 1149 1150
			}
		}));

A
Alex Dima 已提交
1151
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
			return getLinks(model).then(value => {
				assert.equal(value.length, 1);
				let [first] = value;

				assert.equal(first.url, 'foo:bar#3');
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 2, endColumn: 2 });
			});
		});
	});

	test('Links, evil provider', function () {

		disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
			provideDocumentLinks() {
1166
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1167 1168 1169 1170 1171 1172 1173 1174 1175
			}
		}));

		disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
			provideDocumentLinks(): any {
				throw new Error();
			}
		}));

A
Alex Dima 已提交
1176
		return rpcProtocol.sync().then(() => {
J
Johannes Rieken 已提交
1177 1178 1179 1180 1181 1182 1183 1184 1185
			return getLinks(model).then(value => {
				assert.equal(value.length, 1);
				let [first] = value;

				assert.equal(first.url, 'foo:bar#3');
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 2, endColumn: 2 });
			});
		});
	});
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207

	test('Document colors, data conversion', function () {

		disposables.push(extHost.registerColorProvider(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))];
			},
			provideColorPresentations(color: vscode.Color, context: { range: vscode.Range, document: vscode.TextDocument }): vscode.ColorPresentation[] {
				return [];
			}
		}));

		return rpcProtocol.sync().then(() => {
			return getColors(model).then(value => {
				assert.equal(value.length, 1);
				let [first] = value;

				assert.deepEqual(first.colorInfo.color, { red: 0.1, green: 0.2, blue: 0.3, alpha: 0.4 });
				assert.deepEqual(first.colorInfo.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 21 });
			});
		});
	});
J
tslint  
Johannes Rieken 已提交
1208
});