extHostLanguageFeatures.test.ts 35.9 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';
13
import * as EditorCommon from 'vs/editor/common/editorCommon';
J
Johannes Rieken 已提交
14 15 16 17 18
import { Model as EditorModel } from 'vs/editor/common/model/model';
import { Position as EditorPosition } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
import { TestThreadService } from './testThreadService';
import { IMarkerService } from 'vs/platform/markers/common/markers';
19
import { MarkerService } from 'vs/platform/markers/common/markerService';
J
Johannes Rieken 已提交
20
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
21
import { MainThreadLanguageFeatures } from 'vs/workbench/api/electron-browser/mainThreadLanguageFeatures';
J
Johannes Rieken 已提交
22
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
23 24
import { MainThreadCommands } from 'vs/workbench/api/electron-browser/mainThreadCommands';
import { IHeapService } from 'vs/workbench/api/electron-browser/mainThreadHeapService';
J
Johannes Rieken 已提交
25
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
J
Johannes Rieken 已提交
26
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
J
Johannes Rieken 已提交
27
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/common/quickOpen';
28
import { DocumentSymbolProviderRegistry, DocumentHighlightKind, Hover } from 'vs/editor/common/modes';
29
import { getCodeLensData } from 'vs/editor/contrib/codelens/browser/codelens';
30
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDeclaration/browser/goToDeclaration';
J
Johannes Rieken 已提交
31 32
import { getHover } from 'vs/editor/contrib/hover/common/hover';
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
33
import { provideReferences } from 'vs/editor/contrib/referenceSearch/browser/referenceSearch';
J
Johannes Rieken 已提交
34
import { getCodeActions } from 'vs/editor/contrib/quickFix/browser/quickFix';
J
Johannes Rieken 已提交
35
import { getWorkspaceSymbols } from 'vs/workbench/parts/search/common/search';
J
Johannes Rieken 已提交
36
import { rename } from 'vs/editor/contrib/rename/browser/rename';
J
Johannes Rieken 已提交
37
import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/common/parameterHints';
38
import { provideSuggestionItems } from 'vs/editor/contrib/suggest/browser/suggest';
J
Johannes Rieken 已提交
39 40 41 42 43 44
import { getDocumentFormattingEdits, getDocumentRangeFormattingEdits, getOnTypeFormattingEdits } from 'vs/editor/contrib/format/common/format';
import { getLinks } from 'vs/editor/contrib/links/common/links';
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';
45
import * as vscode from 'vscode';
B
Benjamin Pasero 已提交
46
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
47 48

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

let extHost: ExtHostLanguageFeatures;
let mainThread: MainThreadLanguageFeatures;
let disposables: vscode.Disposable[] = [];
62
let threadService: TestThreadService;
63 64
let originalErrorHandler: (e: any) => any;

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

	suiteSetup(() => {

A
Alex Dima 已提交
69
		threadService = new TestThreadService();
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

		// 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 已提交
85

86 87 88
		originalErrorHandler = errorHandler.getUnexpectedErrorHandler();
		setUnexpectedErrorHandler(() => { });

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

103 104
		const heapService = new ExtHostHeapService();

105
		const commands = new ExtHostCommands(threadService, heapService);
106
		threadService.set(ExtHostContext.ExtHostCommands, commands);
107
		threadService.setTestInstance(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, threadService));
108

109 110
		const diagnostics = new ExtHostDiagnostics(threadService);
		threadService.set(ExtHostContext.ExtHostDiagnostics, diagnostics);
111

112
		extHost = new ExtHostLanguageFeatures(threadService, extHostDocuments, commands, heapService, diagnostics);
113
		threadService.set(ExtHostContext.ExtHostLanguageFeatures, extHost);
114

115
		mainThread = <MainThreadLanguageFeatures>threadService.setTestInstance(MainContext.MainThreadLanguageFeatures, inst.createInstance(MainThreadLanguageFeatures, threadService));
116 117 118 119
	});

	suiteTeardown(() => {
		setUnexpectedErrorHandler(originalErrorHandler);
120
		model.dispose();
121 122
	});

J
Johannes Rieken 已提交
123
	teardown(function () {
124 125 126
		while (disposables.length) {
			disposables.pop().dispose();
		}
127
		return threadService.sync();
128 129
	});

130 131
	// --- outline

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

140
		return threadService.sync().then(() => {
141
			assert.equal(DocumentSymbolProviderRegistry.all(model).length, 1);
142
			d1.dispose();
143
			return threadService.sync();
144 145 146 147
		});

	});

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

160
		return threadService.sync().then(() => {
161

162
			return getDocumentSymbols(model).then(value => {
163 164 165 166 167
				assert.equal(value.entries.length, 1);
			});
		});
	});

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

175
		return threadService.sync().then(() => {
176

177
			return getDocumentSymbols(model).then(value => {
178 179 180
				assert.equal(value.entries.length, 1);

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

	// --- code lens

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

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

202 203
		return threadService.sync().then(() => {
			return getCodeLensData(model).then(value => {
204 205 206 207 208
				assert.equal(value.length, 1);
			});
		});
	});

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

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

222
		return threadService.sync().then(() => {
223

224
			return getCodeLensData(model).then(value => {
225 226 227
				assert.equal(value.length, 1);
				let data = value[0];

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

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

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

246
		return threadService.sync().then(() => {
247

248
			return getCodeLensData(model).then(value => {
249 250 251
				assert.equal(value.length, 1);

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

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

	// --- definition

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

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

273
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
274

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

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

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

297
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
298

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

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

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

313 314 315 316 317
		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 已提交
318

319
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
320

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

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

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

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

344
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
345

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

352
	// --- implementation
353

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

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

		return threadService.sync().then(() => {
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
			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))];
			}
		}));

		return threadService.sync().then(() => {
			return getTypeDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
384 385 386 387 388 389 390 391
				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 已提交
392 393
	// --- extra info

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

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

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

411

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

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

420
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
421

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


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


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

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

455

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

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

469
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
470

471
			getHover(model, new EditorPosition(1, 1)).then(value => {
472 473 474 475 476 477 478 479

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

	// --- occurrences

J
Johannes Rieken 已提交
480
	test('Occurrences, data conversion', function () {
481 482 483

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

488
		return threadService.sync().then(() => {
489

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

J
Johannes Rieken 已提交
499
	test('Occurrences, order 1/2', function () {
500 501 502

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

512
		return threadService.sync().then(() => {
513

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

J
Johannes Rieken 已提交
523
	test('Occurrences, order 2/2', function () {
524 525 526

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

536
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
537

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

J
Johannes Rieken 已提交
547
	test('Occurrences, evil provider', function () {
548 549 550 551 552 553 554 555 556

		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 已提交
557
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
558 559 560
			}
		}));

561
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
562

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

	// --- references

571
	test('References, registration order', function () {
J
Johannes Rieken 已提交
572 573 574 575 576 577 578

		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))];
			}
		}));

579 580 581 582 583
		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 已提交
584

585
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
586

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

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

J
Johannes Rieken 已提交
597
	test('References, data conversion', function () {
J
Johannes Rieken 已提交
598 599 600

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

605
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
606

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

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

		});
	});

J
Johannes Rieken 已提交
618
	test('References, evil provider', function () {
J
Johannes Rieken 已提交
619 620 621 622 623 624 625 626

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

631
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
632

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

		});
	});
J
Johannes Rieken 已提交
639 640 641

	// --- quick fix

J
Johannes Rieken 已提交
642
	test('Quick Fix, data conversion', function () {
J
Johannes Rieken 已提交
643 644 645 646

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

653
		return threadService.sync().then(() => {
654
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
655 656 657
				assert.equal(value.length, 2);

				let [first, second] = value;
J
Johannes Rieken 已提交
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
				assert.equal(first.title, 'Testing1');
				assert.equal(first.id, 'test1');
				assert.equal(second.title, 'Testing2');
				assert.equal(second.id, 'test2');
			});
		});
	});

	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' }
				];
			}
		}));

		return threadService.sync().then(() => {
			return getCodeActions(model, model.getFullModelRange()).then(value => {
				assert.equal(value.length, 1);
J
Johannes Rieken 已提交
681 682 683 684
			});
		});
	});

J
Johannes Rieken 已提交
685
	test('Quick Fix, evil provider', function () {
J
Johannes Rieken 已提交
686 687 688 689 690 691 692 693 694 695 696 697

		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' }];
			}
		}));

698
		return threadService.sync().then(() => {
699
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
700 701 702 703
				assert.equal(value.length, 1);
			});
		});
	});
704 705 706

	// --- navigate types

J
Johannes Rieken 已提交
707
	test('Navigate types, evil provider', function () {
708 709 710 711 712 713 714 715 716

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

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

721
		return threadService.sync().then(() => {
722

723
			return getWorkspaceSymbols('').then(value => {
724
				assert.equal(value.length, 1);
725 726 727 728
				const [first] = value;
				const [, symbols] = first;
				assert.equal(symbols.length, 1);
				assert.equal(symbols[0].name, 'testing');
729 730
			});
		});
J
Johannes Rieken 已提交
731 732 733 734
	});

	// --- rename

J
Johannes Rieken 已提交
735
	test('Rename, evil provider 1/2', function () {
J
Johannes Rieken 已提交
736 737 738 739 740 741 742

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

743
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
744

745
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
746
				throw new Error('');
J
Johannes Rieken 已提交
747
			}, err => {
748
				// expected
J
Johannes Rieken 已提交
749 750 751 752
			});
		});
	});

J
Johannes Rieken 已提交
753
	test('Rename, evil provider 2/2', function () {
J
Johannes Rieken 已提交
754 755 756 757 758 759 760 761 762 763

		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();
764
				edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
J
Johannes Rieken 已提交
765 766 767 768
				return edit;
			}
		}));

769
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
770

771
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
772 773 774 775 776
				assert.equal(value.edits.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
777
	test('Rename, ordering', function () {
J
Johannes Rieken 已提交
778 779 780 781

		disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
			provideRenameEdits(): any {
				let edit = new types.WorkspaceEdit();
782 783
				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 已提交
784 785 786 787 788 789 790 791 792 793
				return edit;
			}
		}));

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

794
		return threadService.sync().then(() => {
J
Johannes Rieken 已提交
795

796
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
797 798 799 800
				assert.equal(value.edits.length, 2); // least relevant renamer
			});
		});
	});
801 802 803

	// --- parameter hints

J
Johannes Rieken 已提交
804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
	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 {
				return new types.SignatureHelp();
			}
		}, []));

		return threadService.sync().then(() => {

			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
				assert.ok(value);
			});
		});
	});
J
Johannes Rieken 已提交
825
	test('Parameter Hints, evil provider', function () {
826 827 828 829 830 831 832

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

833
		return threadService.sync().then(() => {
834

835
			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
836
				assert.equal(value, undefined);
B
Benjamin Pasero 已提交
837
			});
838
		});
839 840 841 842
	});

	// --- suggestions

J
Johannes Rieken 已提交
843
	test('Suggest, order 1/3', function () {
844 845 846 847 848 849 850 851 852 853 854 855 856

		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')];
			}
		}, []));

857
		return threadService.sync().then(() => {
858
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
859
				assert.equal(value.length, 1);
860
				assert.equal(value[0].suggestion.insertText, 'testing2');
861 862 863 864
			});
		});
	});

J
Johannes Rieken 已提交
865
	test('Suggest, order 2/3', function () {
866 867 868 869 870 871 872 873 874 875 876 877 878

		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;
			}
		}, []));

879
		return threadService.sync().then(() => {
880
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
881
				assert.equal(value.length, 1);
882
				assert.equal(value[0].suggestion.insertText, 'weak-selector');
883 884
			});
		});
B
Benjamin Pasero 已提交
885
	});
886

887
	test('Suggest, order 2/3', function () {
888 889 890 891 892 893 894

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

895 896 897 898 899 900 901
		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('strong-2')];
			}
		}, []));

		return threadService.sync().then(() => {
902
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
903
				assert.equal(value.length, 2);
904 905
				assert.equal(value[0].suggestion.insertText, 'strong-1'); // sort by label
				assert.equal(value[1].suggestion.insertText, 'strong-2');
906
			});
907
		});
B
Benjamin Pasero 已提交
908
	});
909

J
Johannes Rieken 已提交
910
	test('Suggest, evil provider', function () {
911 912 913 914 915 916 917 918 919 920 921 922 923 924

		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')];
			}
		}, []));


925
		return threadService.sync().then(() => {
926

927
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
928
				assert.equal(value[0].container.incomplete, undefined);
929 930 931
			});
		});
	});
932

J
Johannes Rieken 已提交
933
	test('Suggest, CompletionList', function () {
934 935 936

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
J
Johannes Rieken 已提交
937
				return new types.CompletionList([<any>new types.CompletionItem('hello')], true);
938 939 940 941 942
			}
		}, []));

		return threadService.sync().then(() => {

943
			provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
944
				assert.equal(value[0].container.incomplete, true);
945 946 947 948
			});
		});
	});

949 950
	// --- format

J
Johannes Rieken 已提交
951
	test('Format Doc, data conversion', function () {
952 953
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
954
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing'), types.TextEdit.setEndOfLine(types.EndOfLine.LF)];
955 956 957
			}
		}));

958
		return threadService.sync().then(() => {
959
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
960 961
				assert.equal(value.length, 2);
				let [first, second] = value;
962
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
963
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
964 965 966 967

				assert.equal(second.eol, EditorCommon.EndOfLineSequence.LF);
				assert.equal(second.text, '');
				assert.equal(second.range, undefined);
968 969 970 971
			});
		});
	});

J
Johannes Rieken 已提交
972
	test('Format Doc, evil provider', function () {
973 974 975 976 977 978
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

979
		return threadService.sync().then(() => {
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 });
		});
	});

	test('Format Doc, order', function () {
		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;
			}
		}));

		return threadService.sync().then(() => {
			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 });
			});
1004 1005 1006
		});
	});

J
Johannes Rieken 已提交
1007
	test('Format Range, data conversion', function () {
1008 1009
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1010
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
1011 1012 1013
			}
		}));

1014
		return threadService.sync().then(() => {
1015
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1016 1017 1018
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
1019
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
1020 1021
			});
		});
B
Benjamin Pasero 已提交
1022
	});
1023

J
Johannes Rieken 已提交
1024
	test('Format Range, + format_doc', function () {
1025 1026
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1027
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'range')];
1028 1029 1030 1031 1032 1033 1034
			}
		}));
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				return [new types.TextEdit(new types.Range(0, 0, 1, 1), 'doc')];
			}
		}));
1035
		return threadService.sync().then(() => {
1036
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1037 1038 1039 1040 1041 1042 1043
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'range');
			});
		});
	});

J
Johannes Rieken 已提交
1044
	test('Format Range, evil provider', function () {
1045 1046 1047 1048 1049 1050
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

1051
		return threadService.sync().then(() => {
1052
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 });
1053
		});
B
Benjamin Pasero 已提交
1054
	});
1055

J
Johannes Rieken 已提交
1056
	test('Format on Type, data conversion', function () {
1057 1058 1059 1060 1061 1062 1063

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

1064
		return threadService.sync().then(() => {
1065
			return getOnTypeFormattingEdits(model, new EditorPosition(1, 1), ';', { insertSpaces: true, tabSize: 2 }).then(value => {
1066 1067 1068 1069 1070 1071 1072 1073
				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 已提交
1074 1075 1076 1077 1078

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

		disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
			provideDocumentLinks() {
1079
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
			}
		}));

		return threadService.sync().then(() => {
			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() {
1098
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
			}
		}));

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

		return threadService.sync().then(() => {
			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 });
			});
		});
	});
J
tslint  
Johannes Rieken 已提交
1118
});