extHostLanguageFeatures.test.ts 35.8 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 21
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures';
22
import { MainThreadLanguageFeatures } from 'vs/workbench/api/electron-browser/mainThreadLanguageFeatures';
J
Johannes Rieken 已提交
23
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
24 25
import { MainThreadCommands } from 'vs/workbench/api/electron-browser/mainThreadCommands';
import { IHeapService } from 'vs/workbench/api/electron-browser/mainThreadHeapService';
J
Johannes Rieken 已提交
26
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
J
Johannes Rieken 已提交
27
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
J
Johannes Rieken 已提交
28
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/common/quickOpen';
29
import { DocumentSymbolProviderRegistry, DocumentHighlightKind, Hover } from 'vs/editor/common/modes';
30
import { getCodeLensData } from 'vs/editor/contrib/codelens/browser/codelens';
31
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDeclaration/browser/goToDeclaration';
J
Johannes Rieken 已提交
32 33
import { getHover } from 'vs/editor/contrib/hover/common/hover';
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
34
import { provideReferences } from 'vs/editor/contrib/referenceSearch/browser/referenceSearch';
J
Johannes Rieken 已提交
35
import { getCodeActions } from 'vs/editor/contrib/quickFix/browser/quickFix';
J
Johannes Rieken 已提交
36
import { getWorkspaceSymbols } from 'vs/workbench/parts/search/common/search';
J
Johannes Rieken 已提交
37
import { rename } from 'vs/editor/contrib/rename/browser/rename';
J
Johannes Rieken 已提交
38
import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/common/parameterHints';
39
import { provideSuggestionItems } from 'vs/editor/contrib/suggest/browser/suggest';
J
Johannes Rieken 已提交
40 41 42 43 44 45
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';
46
import * as vscode from 'vscode';
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();
J
Johannes Rieken 已提交
70
		let instantiationService = new TestInstantiationService();
71
		instantiationService.stub(IThreadService, threadService);
72
		instantiationService.stub(IMarkerService, MarkerService);
73 74 75 76 77 78 79
		instantiationService.stub(IHeapService, {
			_serviceBrand: undefined,
			trackRecursive(args) {
				// nothing
				return args;
			}
		});
J
Johannes Rieken 已提交
80

81 82 83
		originalErrorHandler = errorHandler.getUnexpectedErrorHandler();
		setUnexpectedErrorHandler(() => { });

J
Johannes Rieken 已提交
84 85 86 87 88 89 90 91 92 93
		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(),
			}]
94
		});
J
Johannes Rieken 已提交
95 96
		const extHostDocuments = new ExtHostDocuments(threadService, extHostDocumentsAndEditors);
		threadService.set(ExtHostContext.ExtHostDocuments, extHostDocuments);
97

98 99
		const heapService = new ExtHostHeapService();

100
		const commands = new ExtHostCommands(threadService, heapService);
101
		threadService.set(ExtHostContext.ExtHostCommands, commands);
102 103
		threadService.setTestInstance(MainContext.MainThreadCommands, instantiationService.createInstance(MainThreadCommands));

104 105
		const diagnostics = new ExtHostDiagnostics(threadService);
		threadService.set(ExtHostContext.ExtHostDiagnostics, diagnostics);
106

107
		extHost = new ExtHostLanguageFeatures(threadService, extHostDocuments, commands, heapService, diagnostics);
108
		threadService.set(ExtHostContext.ExtHostLanguageFeatures, extHost);
109

110
		mainThread = <MainThreadLanguageFeatures>threadService.setTestInstance(MainContext.MainThreadLanguageFeatures, instantiationService.createInstance(MainThreadLanguageFeatures));
111 112 113 114
	});

	suiteTeardown(() => {
		setUnexpectedErrorHandler(originalErrorHandler);
115
		model.dispose();
116 117
	});

J
Johannes Rieken 已提交
118
	teardown(function () {
119 120 121
		while (disposables.length) {
			disposables.pop().dispose();
		}
122
		return threadService.sync();
123 124
	});

125 126
	// --- outline

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

135
		return threadService.sync().then(() => {
136
			assert.equal(DocumentSymbolProviderRegistry.all(model).length, 1);
137
			d1.dispose();
138
			return threadService.sync();
139 140 141 142
		});

	});

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

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

157
			return getDocumentSymbols(model).then(value => {
158 159 160 161 162
				assert.equal(value.entries.length, 1);
			});
		});
	});

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

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

172
			return getDocumentSymbols(model).then(value => {
173 174 175
				assert.equal(value.entries.length, 1);

				let entry = value.entries[0];
176 177
				assert.equal(entry.name, 'test');
				assert.deepEqual(entry.location.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
178 179 180
			});
		});
	});
181 182 183

	// --- code lens

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

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

197 198
		return threadService.sync().then(() => {
			return getCodeLensData(model).then(value => {
199 200 201 202 203
				assert.equal(value.length, 1);
			});
		});
	});

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

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

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

219
			return getCodeLensData(model).then(value => {
220 221 222
				assert.equal(value.length, 1);
				let data = value[0];

223
				return asWinJsPromise((token) => {
224
					return data.provider.resolveCodeLens(model, data.symbol, token);
225
				}).then(symbol => {
J
Johannes Rieken 已提交
226 227
					assert.equal(symbol.command.id, 'id');
					assert.equal(symbol.command.title, 'Title');
228 229 230 231 232
				});
			});
		});
	});

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

235
		disposables.push(extHost.registerCodeLensProvider(defaultSelector, <vscode.CodeLensProvider>{
236 237 238 239 240
			provideCodeLenses() {
				return [new types.CodeLens(new types.Range(0, 0, 0, 0))];
			}
		}));

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

243
			return getCodeLensData(model).then(value => {
244 245 246
				assert.equal(value.length, 1);

				let data = value[0];
247
				return asWinJsPromise((token) => {
248
					return data.provider.resolveCodeLens(model, data.symbol, token);
249
				}).then(symbol => {
250

J
Johannes Rieken 已提交
251 252
					assert.equal(symbol.command.id, 'missing');
					assert.equal(symbol.command.title, '<<MISSING COMMAND>>');
253 254 255 256
				});
			});
		});
	});
J
Johannes Rieken 已提交
257 258 259

	// --- definition

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

262
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
263
			provideDefinition(): any {
264
				return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
J
Johannes Rieken 已提交
265 266 267
			}
		}));

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

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

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

281
		disposables.push(extHost.registerDefinitionProvider(defaultSelector, <vscode.DefinitionProvider>{
J
Johannes Rieken 已提交
282
			provideDefinition(): any {
283
				return [new types.Location(model.uri, new types.Range(1, 1, 1, 1))];
J
Johannes Rieken 已提交
284 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
			}
		}));

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

294
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
295 296 297 298 299
				assert.equal(value.length, 2);
			});
		});
	});

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

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

308 309 310 311 312
		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 已提交
313

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

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

320 321
				assert.equal(value[0].uri.authority, 'second');
				assert.equal(value[1].uri.authority, 'first');
J
Johannes Rieken 已提交
322
			});
323
		});
J
Johannes Rieken 已提交
324 325
	});

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

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

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

341
			return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
342 343 344 345
				assert.equal(value.length, 1);
			});
		});
	});
J
Johannes Rieken 已提交
346

347
	// --- implementation
348

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

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

		return threadService.sync().then(() => {
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
			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 => {
379 380 381 382 383 384 385 386
				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 已提交
387 388
	// --- extra info

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

391
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
392
			provideHover(): any {
B
Benjamin Pasero 已提交
393
				return new types.Hover('Hello');
J
Johannes Rieken 已提交
394 395 396
			}
		}));

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

406

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

409
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
410 411 412 413 414
			provideHover(): any {
				return new types.Hover('Hello', new types.Range(3, 0, 8, 7));
			}
		}));

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

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


426
	test('HoverProvider, registration order', function () {
427
		disposables.push(extHost.registerHoverProvider(defaultSelector, <vscode.HoverProvider>{
J
Johannes Rieken 已提交
428 429 430 431 432 433
			provideHover(): any {
				return new types.Hover('registered first');
			}
		}));


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

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

450

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

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

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

466
			getHover(model, new EditorPosition(1, 1)).then(value => {
467 468 469 470 471 472 473 474

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

	// --- occurrences

J
Johannes Rieken 已提交
475
	test('Occurrences, data conversion', function () {
476 477 478

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

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

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

J
Johannes Rieken 已提交
494
	test('Occurrences, order 1/2', function () {
495 496 497

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

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

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

J
Johannes Rieken 已提交
518
	test('Occurrences, order 2/2', function () {
519 520 521

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

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

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

J
Johannes Rieken 已提交
542
	test('Occurrences, evil provider', function () {
543 544 545 546 547 548 549 550 551

		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 已提交
552
				return [new types.DocumentHighlight(new types.Range(0, 0, 0, 4))];
553 554 555
			}
		}));

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

558
			return getOccurrencesAtPosition(model, new EditorPosition(1, 2)).then(value => {
559 560 561
				assert.equal(value.length, 1);
			});
		});
J
Johannes Rieken 已提交
562
	});
J
Johannes Rieken 已提交
563 564 565

	// --- references

566
	test('References, registration order', function () {
J
Johannes Rieken 已提交
567 568 569 570 571 572 573

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

574 575 576 577 578
		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 已提交
579

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

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

585
				let [first, second] = value;
586 587
				assert.equal(first.uri.path, '/second');
				assert.equal(second.uri.path, '/first');
J
Johannes Rieken 已提交
588
			});
589
		});
J
Johannes Rieken 已提交
590 591
	});

J
Johannes Rieken 已提交
592
	test('References, data conversion', function () {
J
Johannes Rieken 已提交
593 594 595

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

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

602
			return provideReferences(model, new EditorPosition(1, 2)).then(value => {
J
Johannes Rieken 已提交
603 604 605 606
				assert.equal(value.length, 1);

				let [item] = value;
				assert.deepEqual(item.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
607
				assert.equal(item.uri.toString(), model.uri.toString());
J
Johannes Rieken 已提交
608 609 610 611 612
			});

		});
	});

J
Johannes Rieken 已提交
613
	test('References, evil provider', function () {
J
Johannes Rieken 已提交
614 615 616 617 618 619 620 621

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

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

628
			return provideReferences(model, new EditorPosition(1, 2)).then(value => {
J
Johannes Rieken 已提交
629 630 631 632 633
				assert.equal(value.length, 1);
			});

		});
	});
J
Johannes Rieken 已提交
634 635 636

	// --- quick fix

J
Johannes Rieken 已提交
637
	test('Quick Fix, data conversion', function () {
J
Johannes Rieken 已提交
638 639 640 641

		disposables.push(extHost.registerCodeActionProvider(defaultSelector, <vscode.CodeActionProvider>{
			provideCodeActions(): any {
				return [
642 643
					<vscode.Command>{ command: 'test1', title: 'Testing1' },
					<vscode.Command>{ command: 'test2', title: 'Testing2' }
J
Johannes Rieken 已提交
644 645 646 647
				];
			}
		}));

648
		return threadService.sync().then(() => {
649
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
650 651 652
				assert.equal(value.length, 2);

				let [first, second] = value;
J
Johannes Rieken 已提交
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
				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 已提交
676 677 678 679
			});
		});
	});

J
Johannes Rieken 已提交
680
	test('Quick Fix, evil provider', function () {
J
Johannes Rieken 已提交
681 682 683 684 685 686 687 688 689 690 691 692

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

693
		return threadService.sync().then(() => {
694
			return getCodeActions(model, model.getFullModelRange()).then(value => {
J
Johannes Rieken 已提交
695 696 697 698
				assert.equal(value.length, 1);
			});
		});
	});
699 700 701

	// --- navigate types

J
Johannes Rieken 已提交
702
	test('Navigate types, evil provider', function () {
703 704 705 706 707 708 709 710 711

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

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

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

718
			return getWorkspaceSymbols('').then(value => {
719
				assert.equal(value.length, 1);
720 721 722 723
				const [first] = value;
				const [, symbols] = first;
				assert.equal(symbols.length, 1);
				assert.equal(symbols[0].name, 'testing');
724 725
			});
		});
J
Johannes Rieken 已提交
726 727 728 729
	});

	// --- rename

J
Johannes Rieken 已提交
730
	test('Rename, evil provider 1/2', function () {
J
Johannes Rieken 已提交
731 732 733 734 735 736 737

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

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

740
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
741
				throw new Error('');
J
Johannes Rieken 已提交
742
			}, err => {
743
				// expected
J
Johannes Rieken 已提交
744 745 746 747
			});
		});
	});

J
Johannes Rieken 已提交
748
	test('Rename, evil provider 2/2', function () {
J
Johannes Rieken 已提交
749 750 751 752 753 754 755 756 757 758

		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();
759
				edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
J
Johannes Rieken 已提交
760 761 762 763
				return edit;
			}
		}));

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

766
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
767 768 769 770 771
				assert.equal(value.edits.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
772
	test('Rename, ordering', function () {
J
Johannes Rieken 已提交
773 774 775 776

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

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

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

791
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
792 793 794 795
				assert.equal(value.edits.length, 2); // least relevant renamer
			});
		});
	});
796 797 798

	// --- parameter hints

J
Johannes Rieken 已提交
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
	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 已提交
820
	test('Parameter Hints, evil provider', function () {
821 822 823 824 825 826 827

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

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

830
			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
831
				assert.equal(value, undefined);
B
Benjamin Pasero 已提交
832
			});
833
		});
834 835 836 837
	});

	// --- suggestions

J
Johannes Rieken 已提交
838
	test('Suggest, order 1/3', function () {
839 840 841 842 843 844 845 846 847 848 849 850 851

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

852
		return threadService.sync().then(() => {
853
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
854
				assert.equal(value.length, 1);
855
				assert.equal(value[0].suggestion.insertText, 'testing2');
856 857 858 859
			});
		});
	});

J
Johannes Rieken 已提交
860
	test('Suggest, order 2/3', function () {
861 862 863 864 865 866 867 868 869 870 871 872 873

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

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

882
	test('Suggest, order 2/3', function () {
883 884 885 886 887 888 889

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

890 891 892 893 894 895 896
		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('strong-2')];
			}
		}, []));

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

J
Johannes Rieken 已提交
905
	test('Suggest, evil provider', function () {
906 907 908 909 910 911 912 913 914 915 916 917 918 919

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


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

922
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
923
				assert.equal(value[0].container.incomplete, undefined);
924 925 926
			});
		});
	});
927

J
Johannes Rieken 已提交
928
	test('Suggest, CompletionList', function () {
929 930 931

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
J
Johannes Rieken 已提交
932
				return new types.CompletionList([<any>new types.CompletionItem('hello')], true);
933 934 935 936 937
			}
		}, []));

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

938
			provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
939
				assert.equal(value[0].container.incomplete, true);
940 941 942 943
			});
		});
	});

944 945
	// --- format

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

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

				assert.equal(second.eol, EditorCommon.EndOfLineSequence.LF);
				assert.equal(second.text, '');
				assert.equal(second.range, undefined);
963 964 965 966
			});
		});
	});

J
Johannes Rieken 已提交
967
	test('Format Doc, evil provider', function () {
968 969 970 971 972 973
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

974
		return threadService.sync().then(() => {
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998
			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 });
			});
999 1000 1001
		});
	});

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

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

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

J
Johannes Rieken 已提交
1039
	test('Format Range, evil provider', function () {
1040 1041 1042 1043 1044 1045
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

1046
		return threadService.sync().then(() => {
1047
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 });
1048
		});
B
Benjamin Pasero 已提交
1049
	});
1050

J
Johannes Rieken 已提交
1051
	test('Format on Type, data conversion', function () {
1052 1053 1054 1055 1056 1057 1058

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

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

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

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

		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() {
1093
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
			}
		}));

		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 已提交
1113
});