extHostLanguageFeatures.test.ts 36.3 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';
27
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/quickOpen';
28
import { DocumentSymbolProviderRegistry, DocumentHighlightKind, Hover } from 'vs/editor/common/modes';
29 30 31 32 33 34
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';
import { getCodeActions } from 'vs/editor/contrib/quickFix/quickFix';
J
Johannes Rieken 已提交
35
import { getWorkspaceSymbols } from 'vs/workbench/parts/search/common/search';
36 37 38 39 40
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 已提交
41 42 43 44
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();

J
Joao Moreno 已提交
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();
J
Johannes Rieken 已提交
121
		mainThread.dispose();
122 123
	});

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

131 132
	// --- outline

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

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

	});

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

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

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

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

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

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

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

	// --- code lens

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// --- definition

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

353
	// --- implementation
354

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

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

		return threadService.sync().then(() => {
364 365 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))];
			}
		}));

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

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

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

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

412

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

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

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

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


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


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

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

456

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

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

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

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

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

	// --- occurrences

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// --- references

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

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

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

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

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

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

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

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

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

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

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

		});
	});

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

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

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

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

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

	// --- quick fix

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

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

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

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

	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 已提交
682 683 684 685
			});
		});
	});

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

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

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

	// --- navigate types

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

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

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

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

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

	// --- rename

J
Johannes Rieken 已提交
736
	test('Rename, evil provider 0/2', function () {
J
Johannes Rieken 已提交
737 738 739

		disposables.push(extHost.registerRenameProvider(defaultSelector, <vscode.RenameProvider>{
			provideRenameEdits(): any {
J
Johannes Rieken 已提交
740
				throw new class Foo { };
J
Johannes Rieken 已提交
741 742 743
			}
		}));

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

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

J
Johannes Rieken 已提交
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
	test('Rename, evil provider 1/2', function () {

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

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

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

J
Johannes Rieken 已提交
770
	test('Rename, evil provider 2/2', function () {
J
Johannes Rieken 已提交
771 772 773 774 775 776 777 778 779 780

		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();
781
				edit.replace(model.uri, new types.Range(0, 0, 0, 0), 'testing');
J
Johannes Rieken 已提交
782 783 784 785
				return edit;
			}
		}));

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

788
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
789 790 791 792 793
				assert.equal(value.edits.length, 1);
			});
		});
	});

J
Johannes Rieken 已提交
794
	test('Rename, ordering', function () {
J
Johannes Rieken 已提交
795 796 797 798

		disposables.push(extHost.registerRenameProvider('*', <vscode.RenameProvider>{
			provideRenameEdits(): any {
				let edit = new types.WorkspaceEdit();
799 800
				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 已提交
801 802 803 804 805 806 807 808 809 810
				return edit;
			}
		}));

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

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

813
			return rename(model, new EditorPosition(1, 1), 'newName').then(value => {
J
Johannes Rieken 已提交
814 815 816 817
				assert.equal(value.edits.length, 2); // least relevant renamer
			});
		});
	});
818 819 820

	// --- parameter hints

J
Johannes Rieken 已提交
821 822 823 824 825 826 827 828 829 830
	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 {
831 832 833 834 835
				return {
					signatures: [],
					activeParameter: 0,
					activeSignature: 0
				};
J
Johannes Rieken 已提交
836 837 838 839 840 841 842 843 844 845
			}
		}, []));

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

			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
				assert.ok(value);
			});
		});
	});
J
Johannes Rieken 已提交
846
	test('Parameter Hints, evil provider', function () {
847 848 849 850 851 852 853

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

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

856
			return provideSignatureHelp(model, new EditorPosition(1, 1)).then(value => {
J
Johannes Rieken 已提交
857
				assert.equal(value, undefined);
B
Benjamin Pasero 已提交
858
			});
859
		});
860 861 862 863
	});

	// --- suggestions

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

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

878
		return threadService.sync().then(() => {
879
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
880
				assert.equal(value.length, 1);
881
				assert.equal(value[0].suggestion.insertText, 'testing2');
882 883 884 885
			});
		});
	});

J
Johannes Rieken 已提交
886
	test('Suggest, order 2/3', function () {
887 888 889 890 891 892 893 894 895 896 897 898 899

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

900
		return threadService.sync().then(() => {
901
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
902
				assert.equal(value.length, 1);
903
				assert.equal(value[0].suggestion.insertText, 'weak-selector');
904 905
			});
		});
B
Benjamin Pasero 已提交
906
	});
907

908
	test('Suggest, order 2/3', function () {
909 910 911 912 913 914 915

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

916 917 918 919 920 921 922
		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
				return [new types.CompletionItem('strong-2')];
			}
		}, []));

		return threadService.sync().then(() => {
923
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
924
				assert.equal(value.length, 2);
925 926
				assert.equal(value[0].suggestion.insertText, 'strong-1'); // sort by label
				assert.equal(value[1].suggestion.insertText, 'strong-2');
927
			});
928
		});
B
Benjamin Pasero 已提交
929
	});
930

J
Johannes Rieken 已提交
931
	test('Suggest, evil provider', function () {
932 933 934 935 936 937 938 939 940 941 942 943 944 945

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


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

948
			return provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
949
				assert.equal(value[0].container.incomplete, undefined);
950 951 952
			});
		});
	});
953

J
Johannes Rieken 已提交
954
	test('Suggest, CompletionList', function () {
955 956 957

		disposables.push(extHost.registerCompletionItemProvider(defaultSelector, <vscode.CompletionItemProvider>{
			provideCompletionItems(): any {
J
Johannes Rieken 已提交
958
				return new types.CompletionList([<any>new types.CompletionItem('hello')], true);
959 960 961 962 963
			}
		}, []));

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

964
			provideSuggestionItems(model, new EditorPosition(1, 1), 'none').then(value => {
965
				assert.equal(value[0].container.incomplete, true);
966 967 968 969
			});
		});
	});

970 971
	// --- format

J
Johannes Rieken 已提交
972
	test('Format Doc, data conversion', function () {
973 974
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
975
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing'), types.TextEdit.setEndOfLine(types.EndOfLine.LF)];
976 977 978
			}
		}));

979
		return threadService.sync().then(() => {
980
			return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }).then(value => {
981 982
				assert.equal(value.length, 2);
				let [first, second] = value;
983
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
984
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
985 986 987 988

				assert.equal(second.eol, EditorCommon.EndOfLineSequence.LF);
				assert.equal(second.text, '');
				assert.equal(second.range, undefined);
989 990 991 992
			});
		});
	});

J
Johannes Rieken 已提交
993
	test('Format Doc, evil provider', function () {
994 995 996 997 998 999
		disposables.push(extHost.registerDocumentFormattingEditProvider(defaultSelector, <vscode.DocumentFormattingEditProvider>{
			provideDocumentFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

1000
		return threadService.sync().then(() => {
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
			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 });
			});
1025 1026 1027
		});
	});

J
Johannes Rieken 已提交
1028
	test('Format Range, data conversion', function () {
1029 1030
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1031
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'testing')];
1032 1033 1034
			}
		}));

1035
		return threadService.sync().then(() => {
1036
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1037 1038 1039
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'testing');
J
Johannes Rieken 已提交
1040
				assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 });
1041 1042
			});
		});
B
Benjamin Pasero 已提交
1043
	});
1044

J
Johannes Rieken 已提交
1045
	test('Format Range, + format_doc', function () {
1046 1047
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
J
Johannes Rieken 已提交
1048
				return [new types.TextEdit(new types.Range(0, 0, 0, 0), 'range')];
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, 1, 1), 'doc')];
			}
		}));
1056
		return threadService.sync().then(() => {
1057
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }).then(value => {
1058 1059 1060 1061 1062 1063 1064
				assert.equal(value.length, 1);
				let [first] = value;
				assert.equal(first.text, 'range');
			});
		});
	});

J
Johannes Rieken 已提交
1065
	test('Format Range, evil provider', function () {
1066 1067 1068 1069 1070 1071
		disposables.push(extHost.registerDocumentRangeFormattingEditProvider(defaultSelector, <vscode.DocumentRangeFormattingEditProvider>{
			provideDocumentRangeFormattingEdits(): any {
				throw new Error('evil');
			}
		}));

1072
		return threadService.sync().then(() => {
1073
			return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 });
1074
		});
B
Benjamin Pasero 已提交
1075
	});
1076

J
Johannes Rieken 已提交
1077
	test('Format on Type, data conversion', function () {
1078 1079 1080 1081 1082 1083 1084

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

1085
		return threadService.sync().then(() => {
1086
			return getOnTypeFormattingEdits(model, new EditorPosition(1, 1), ';', { insertSpaces: true, tabSize: 2 }).then(value => {
1087 1088 1089 1090 1091 1092 1093 1094
				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 已提交
1095 1096 1097 1098 1099

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

		disposables.push(extHost.registerDocumentLinkProvider(defaultSelector, <vscode.DocumentLinkProvider>{
			provideDocumentLinks() {
1100
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
			}
		}));

		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() {
1119
				return [new types.DocumentLink(new types.Range(0, 0, 1, 1), URI.parse('foo:bar#3'))];
J
Johannes Rieken 已提交
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
			}
		}));

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