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

import * as assert from 'assert';
7
import { IEditorModel } from 'vs/platform/editor/common/editor';
8
import { URI } from 'vs/base/common/uri';
9
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
10
import { EditorInput, EditorOptions, IFileEditorInput, IEditorInput } from 'vs/workbench/common/editor';
11
import { workbenchInstantiationService, TestStorageService } from 'vs/workbench/test/workbenchTestServices';
12 13
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
B
Benjamin Pasero 已提交
14
import { EditorService, DelegatingEditorService } from 'vs/workbench/services/editor/browser/editorService';
15
import { IEditorGroup, IEditorGroupsService, GroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService';
16
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
17
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
18
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
19 20 21 22 23
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IEditorRegistry, EditorDescriptor, Extensions } from 'vs/workbench/browser/editor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { Registry } from 'vs/platform/registry/common/platform';
24
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
B
Benjamin Pasero 已提交
25
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
B
Benjamin Pasero 已提交
26
import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
27
import { CancellationToken } from 'vs/base/common/cancellation';
B
Benjamin Pasero 已提交
28
import { timeout } from 'vs/base/common/async';
29
import { toResource } from 'vs/base/test/common/utils';
30 31 32

export class TestEditorControl extends BaseEditor {

33
	constructor(@ITelemetryService telemetryService: ITelemetryService) { super('MyTestEditorForEditorService', NullTelemetryService, new TestThemeService(), new TestStorageService()); }
34

J
Johannes Rieken 已提交
35
	setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
36 37
		super.setInput(input, options, token);

R
Rob Lourens 已提交
38
		return input.resolve().then(() => undefined);
39 40
	}

B
Benjamin Pasero 已提交
41
	getId(): string { return 'MyTestEditorForEditorService'; }
42 43 44 45 46
	layout(): void { }
	createEditor(): any { }
}

export class TestEditorInput extends EditorInput implements IFileEditorInput {
B
Benjamin Pasero 已提交
47
	public gotDisposed: boolean;
48
	private fails: boolean;
49 50
	constructor(private resource: URI) { super(); }

51
	getTypeId() { return 'testEditorInputForEditorService'; }
J
Johannes Rieken 已提交
52
	resolve(): Promise<IEditorModel> { return !this.fails ? Promise.resolve(null) : Promise.reject(new Error('fails')); }
B
Benjamin Pasero 已提交
53
	matches(other: TestEditorInput): boolean { return other && other.resource && this.resource.toString() === other.resource.toString() && other instanceof TestEditorInput; }
54
	setEncoding(encoding: string) { }
M
Matt Bierner 已提交
55
	getEncoding(): string { return null!; }
56 57 58
	setPreferredEncoding(encoding: string) { }
	getResource(): URI { return this.resource; }
	setForceOpenAsBinary(): void { }
59 60 61
	setFailToOpen(): void {
		this.fails = true;
	}
B
Benjamin Pasero 已提交
62 63 64 65
	dispose(): void {
		super.dispose();
		this.gotDisposed = true;
	}
66 67
}

68
suite('Editor service', () => {
69

B
Benjamin Pasero 已提交
70
	function registerTestEditorInput(): void {
71
		Registry.as<IEditorRegistry>(Extensions.Editors).registerEditor(new EditorDescriptor(TestEditorControl, 'MyTestEditorForEditorService', 'My Test Editor For Next Editor Service'), new SyncDescriptor(TestEditorInput));
B
Benjamin Pasero 已提交
72 73 74 75
	}

	registerTestEditorInput();

76 77 78
	test('basics', function () {
		const partInstantiator = workbenchInstantiationService();

79
		const part = partInstantiator.createInstance(EditorPart);
80
		part.create(document.createElement('div'));
81
		part.layout(400, 300);
82

83
		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));
84

B
Benjamin Pasero 已提交
85
		const service: EditorServiceImpl = testInstantiationService.createInstance(EditorService);
86

B
Benjamin Pasero 已提交
87 88
		const input = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource-basics'));
		const otherInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource2-basics'));
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

		let activeEditorChangeEventCounter = 0;
		const activeEditorChangeListener = service.onDidActiveEditorChange(() => {
			activeEditorChangeEventCounter++;
		});

		let visibleEditorChangeEventCounter = 0;
		const visibleEditorChangeListener = service.onDidVisibleEditorsChange(() => {
			visibleEditorChangeEventCounter++;
		});

		let didCloseEditorListenerCounter = 0;
		const didCloseEditorListener = service.onDidCloseEditor(editor => {
			didCloseEditorListenerCounter++;
		});

105
		return part.whenRestored.then(() => {
B
Benjamin Pasero 已提交
106

107 108 109 110 111 112 113 114 115 116 117 118 119 120
			// Open input
			return service.openEditor(input, { pinned: true }).then(editor => {
				assert.ok(editor instanceof TestEditorControl);
				assert.equal(editor, service.activeControl);
				assert.equal(input, service.activeEditor);
				assert.equal(service.visibleControls.length, 1);
				assert.equal(service.visibleControls[0], editor);
				assert.ok(!service.activeTextEditorWidget);
				assert.equal(service.visibleTextEditorWidgets.length, 0);
				assert.equal(service.isOpen(input), true);
				assert.equal(service.getOpened({ resource: input.getResource() }), input);
				assert.equal(service.isOpen(input, part.activeGroup), true);
				assert.equal(activeEditorChangeEventCounter, 1);
				assert.equal(visibleEditorChangeEventCounter, 1);
B
Benjamin Pasero 已提交
121

122
				// Close input
M
Matt Bierner 已提交
123
				return editor!.group!.closeEditor(input).then(() => {
B
Benjamin Pasero 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
					assert.equal(didCloseEditorListenerCounter, 1);
					assert.equal(activeEditorChangeEventCounter, 2);
					assert.equal(visibleEditorChangeEventCounter, 2);
					assert.ok(input.gotDisposed);

					// Open again 2 inputs
					return service.openEditor(input, { pinned: true }).then(editor => {
						return service.openEditor(otherInput, { pinned: true }).then(editor => {
							assert.equal(service.visibleControls.length, 1);
							assert.equal(service.isOpen(input), true);
							assert.equal(service.isOpen(otherInput), true);

							assert.equal(activeEditorChangeEventCounter, 4);
							assert.equal(visibleEditorChangeEventCounter, 4);

							activeEditorChangeListener.dispose();
							visibleEditorChangeListener.dispose();
							didCloseEditorListener.dispose();
						});
143
					});
B
Benjamin Pasero 已提交
144 145
				});
			});
146 147 148
		});
	});

149 150 151
	test('openEditors() / replaceEditors()', function () {
		const partInstantiator = workbenchInstantiationService();

152
		const part = partInstantiator.createInstance(EditorPart);
153
		part.create(document.createElement('div'));
154
		part.layout(400, 300);
155

156
		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));
157

158
		const service: IEditorService = testInstantiationService.createInstance(EditorService);
159

B
Benjamin Pasero 已提交
160 161 162
		const input = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource-openEditors'));
		const otherInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource2-openEditors'));
		const replaceInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource3-openEditors'));
163

164
		return part.whenRestored.then(() => {
165

166 167
			// Open editors
			return service.openEditors([{ editor: input }, { editor: otherInput }]).then(() => {
168
				assert.equal(part.activeGroup.count, 2);
169 170 171 172 173

				return service.replaceEditors([{ editor: input, replacement: replaceInput }], part.activeGroup).then(() => {
					assert.equal(part.activeGroup.count, 2);
					assert.equal(part.activeGroup.getIndexOfEditor(replaceInput), 0);
				});
174 175 176 177
			});
		});
	});

178 179
	test('caching', function () {
		const instantiationService = workbenchInstantiationService();
180
		const service: EditorService = <any>instantiationService.createInstance(EditorService);
181 182

		// Cached Input (Files)
183
		const fileResource1 = toResource.call(this, '/foo/bar/cache1.js');
184 185 186
		const fileInput1 = service.createInput({ resource: fileResource1 });
		assert.ok(fileInput1);

187
		const fileResource2 = toResource.call(this, '/foo/bar/cache2.js');
188 189 190 191 192 193 194 195
		const fileInput2 = service.createInput({ resource: fileResource2 });
		assert.ok(fileInput2);

		assert.notEqual(fileInput1, fileInput2);

		const fileInput1Again = service.createInput({ resource: fileResource1 });
		assert.equal(fileInput1Again, fileInput1);

M
Matt Bierner 已提交
196
		fileInput1Again!.dispose();
197

M
Matt Bierner 已提交
198
		assert.ok(fileInput1!.isDisposed());
199 200 201

		const fileInput1AgainAndAgain = service.createInput({ resource: fileResource1 });
		assert.notEqual(fileInput1AgainAndAgain, fileInput1);
M
Matt Bierner 已提交
202
		assert.ok(!fileInput1AgainAndAgain!.isDisposed());
203 204

		// Cached Input (Resource)
205
		const resource1 = URI.from({ scheme: 'custom', path: '/foo/bar/cache1.js' });
206 207 208
		const input1 = service.createInput({ resource: resource1 });
		assert.ok(input1);

209
		const resource2 = URI.from({ scheme: 'custom', path: '/foo/bar/cache2.js' });
210 211 212 213 214 215 216 217
		const input2 = service.createInput({ resource: resource2 });
		assert.ok(input2);

		assert.notEqual(input1, input2);

		const input1Again = service.createInput({ resource: resource1 });
		assert.equal(input1Again, input1);

M
Matt Bierner 已提交
218
		input1Again!.dispose();
219

M
Matt Bierner 已提交
220
		assert.ok(input1!.isDisposed());
221 222 223

		const input1AgainAndAgain = service.createInput({ resource: resource1 });
		assert.notEqual(input1AgainAndAgain, input1);
M
Matt Bierner 已提交
224
		assert.ok(!input1AgainAndAgain!.isDisposed());
225 226
	});

B
Benjamin Pasero 已提交
227 228
	test('createInput', function () {
		const instantiationService = workbenchInstantiationService();
229
		const service: EditorService = <any>instantiationService.createInstance(EditorService);
B
Benjamin Pasero 已提交
230 231

		// Untyped Input (file)
232
		let input = service.createInput({ resource: toResource.call(this, '/index.html'), options: { selection: { startLineNumber: 1, startColumn: 1 } } });
B
Benjamin Pasero 已提交
233 234
		assert(input instanceof FileEditorInput);
		let contentInput = <FileEditorInput>input;
235
		assert.strictEqual(contentInput.getResource().fsPath, toResource.call(this, '/index.html').fsPath);
B
Benjamin Pasero 已提交
236 237

		// Untyped Input (file, encoding)
238
		input = service.createInput({ resource: toResource.call(this, '/index.html'), encoding: 'utf16le', options: { selection: { startLineNumber: 1, startColumn: 1 } } });
B
Benjamin Pasero 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
		assert(input instanceof FileEditorInput);
		contentInput = <FileEditorInput>input;
		assert.equal(contentInput.getPreferredEncoding(), 'utf16le');

		// Untyped Input (untitled)
		input = service.createInput({ options: { selection: { startLineNumber: 1, startColumn: 1 } } });
		assert(input instanceof UntitledEditorInput);

		// Untyped Input (untitled with contents)
		input = service.createInput({ contents: 'Hello Untitled', options: { selection: { startLineNumber: 1, startColumn: 1 } } });
		assert(input instanceof UntitledEditorInput);

		// Untyped Input (untitled with file path)
		input = service.createInput({ filePath: '/some/path.txt', options: { selection: { startLineNumber: 1, startColumn: 1 } } });
		assert(input instanceof UntitledEditorInput);
		assert.ok((input as UntitledEditorInput).hasAssociatedFilePath);
	});

257 258 259 260 261 262
	test('delegate', function (done) {
		const instantiationService = workbenchInstantiationService();

		class MyEditor extends BaseEditor {

			constructor(id: string) {
M
Matt Bierner 已提交
263
				super(id, undefined!, new TestThemeService(), new TestStorageService());
264 265 266 267 268 269
			}

			getId(): string {
				return 'myEditor';
			}

B
Benjamin Pasero 已提交
270
			layout(): void { }
271

B
Benjamin Pasero 已提交
272
			createEditor(): any { }
273 274 275 276
		}

		const ed = instantiationService.createInstance(MyEditor, 'my.editor');

B
Benjamin Pasero 已提交
277
		const inp = instantiationService.createInstance(ResourceEditorInput, 'name', 'description', URI.parse('my://resource-delegate'));
B
Benjamin Pasero 已提交
278
		const delegate = instantiationService.createInstance(DelegatingEditorService);
279
		delegate.setEditorOpenHandler((group: IEditorGroup, input: IEditorInput, options?: EditorOptions) => {
280 281 282 283
			assert.strictEqual(input, inp);

			done();

B
Benjamin Pasero 已提交
284
			return Promise.resolve(ed);
285 286 287 288
		});

		delegate.openEditor(inp);
	});
B
Benjamin Pasero 已提交
289 290 291 292

	test('close editor does not dispose when editor opened in other group', function () {
		const partInstantiator = workbenchInstantiationService();

293
		const part = partInstantiator.createInstance(EditorPart);
B
Benjamin Pasero 已提交
294
		part.create(document.createElement('div'));
295
		part.layout(400, 300);
B
Benjamin Pasero 已提交
296

297
		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));
B
Benjamin Pasero 已提交
298

299
		const service: IEditorService = testInstantiationService.createInstance(EditorService);
B
Benjamin Pasero 已提交
300

B
Benjamin Pasero 已提交
301
		const input = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource-close1'));
B
Benjamin Pasero 已提交
302 303 304 305

		const rootGroup = part.activeGroup;
		const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT);

306
		return part.whenRestored.then(() => {
B
Benjamin Pasero 已提交
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
			// Open input
			return service.openEditor(input, { pinned: true }).then(editor => {
				return service.openEditor(input, { pinned: true }, rightGroup).then(editor => {
					const editors = service.editors;
					assert.equal(editors.length, 2);
					assert.equal(editors[0], input);
					assert.equal(editors[1], input);

					// Close input
					return rootGroup.closeEditor(input).then(() => {
						assert.equal(input.isDisposed(), false);

						return rightGroup.closeEditor(input).then(() => {
							assert.equal(input.isDisposed(), true);
						});
B
Benjamin Pasero 已提交
323 324 325 326 327 328
					});
				});
			});
		});
	});

329 330 331
	test('open to the side', function () {
		const partInstantiator = workbenchInstantiationService();

332
		const part = partInstantiator.createInstance(EditorPart);
333
		part.create(document.createElement('div'));
334
		part.layout(400, 300);
335

336
		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));
337

338
		const service: IEditorService = testInstantiationService.createInstance(EditorService);
339

B
Benjamin Pasero 已提交
340 341
		const input1 = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource1-openside'));
		const input2 = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource2-openside'));
342 343 344

		const rootGroup = part.activeGroup;

345 346 347
		return part.whenRestored.then(() => {
			return service.openEditor(input1, { pinned: true }, rootGroup).then(editor => {
				return service.openEditor(input1, { pinned: true, preserveFocus: true }, SIDE_GROUP).then(editor => {
348 349
					assert.equal(part.activeGroup, rootGroup);
					assert.equal(part.count, 2);
M
Matt Bierner 已提交
350
					assert.equal(editor!.group, part.groups[1]);
351 352 353 354 355

					// Open to the side uses existing neighbour group if any
					return service.openEditor(input2, { pinned: true, preserveFocus: true }, SIDE_GROUP).then(editor => {
						assert.equal(part.activeGroup, rootGroup);
						assert.equal(part.count, 2);
M
Matt Bierner 已提交
356
						assert.equal(editor!.group, part.groups[1]);
357
					});
358 359 360 361
				});
			});
		});
	});
B
Benjamin Pasero 已提交
362

363
	test('active editor change / visible editor change events', async function () {
B
Benjamin Pasero 已提交
364 365
		const partInstantiator = workbenchInstantiationService();

366
		const part = partInstantiator.createInstance(EditorPart);
B
Benjamin Pasero 已提交
367
		part.create(document.createElement('div'));
368
		part.layout(400, 300);
B
Benjamin Pasero 已提交
369 370 371

		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));

B
Benjamin Pasero 已提交
372
		const service: EditorServiceImpl = testInstantiationService.createInstance(EditorService);
B
Benjamin Pasero 已提交
373

B
Benjamin Pasero 已提交
374 375
		const input = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource-active'));
		const otherInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource2-active'));
B
Benjamin Pasero 已提交
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396

		let activeEditorChangeEventFired = false;
		const activeEditorChangeListener = service.onDidActiveEditorChange(() => {
			activeEditorChangeEventFired = true;
		});

		let visibleEditorChangeEventFired = false;
		const visibleEditorChangeListener = service.onDidVisibleEditorsChange(() => {
			visibleEditorChangeEventFired = true;
		});

		function assertActiveEditorChangedEvent(expected: boolean) {
			assert.equal(activeEditorChangeEventFired, expected, `Unexpected active editor change state (got ${activeEditorChangeEventFired}, expected ${expected})`);
			activeEditorChangeEventFired = false;
		}

		function assertVisibleEditorsChangedEvent(expected: boolean) {
			assert.equal(visibleEditorChangeEventFired, expected, `Unexpected visible editors change state (got ${visibleEditorChangeEventFired}, expected ${expected})`);
			visibleEditorChangeEventFired = false;
		}

B
Benjamin Pasero 已提交
397 398 399 400 401
		async function closeEditorAndWaitForNextToOpen(group: IEditorGroup, input: EditorInput): Promise<void> {
			await group.closeEditor(input);
			await timeout(0); // closing an editor will not immediately open the next one, so we need to wait
		}

402 403
		await part.whenRestored;

B
Benjamin Pasero 已提交
404 405
		// 1.) open, open same, open other, close
		let editor = await service.openEditor(input, { pinned: true });
M
Matt Bierner 已提交
406
		const group = editor!.group!;
B
Benjamin Pasero 已提交
407 408 409 410 411 412 413 414 415 416 417
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		editor = await service.openEditor(input);
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

		editor = await service.openEditor(otherInput);
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

B
Benjamin Pasero 已提交
418
		await closeEditorAndWaitForNextToOpen(group, otherInput);
B
Benjamin Pasero 已提交
419 420 421
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

B
Benjamin Pasero 已提交
422
		await closeEditorAndWaitForNextToOpen(group, input);
B
Benjamin Pasero 已提交
423 424 425
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

426
		// 2.) open, open same (forced open)
B
Benjamin Pasero 已提交
427 428 429 430
		editor = await service.openEditor(input);
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

431
		editor = await service.openEditor(input, { forceReload: true });
B
Benjamin Pasero 已提交
432 433 434
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
435
		await closeEditorAndWaitForNextToOpen(group, input);
B
Benjamin Pasero 已提交
436 437 438 439 440 441 442 443 444 445

		// 3.) open, open inactive, close
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		editor = await service.openEditor(otherInput, { inactive: true });
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

446
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
447 448 449 450 451 452 453 454 455 456 457 458
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		// 4.) open, open inactive, close inactive
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		editor = await service.openEditor(otherInput, { inactive: true });
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
459
		await closeEditorAndWaitForNextToOpen(group, otherInput);
B
Benjamin Pasero 已提交
460 461 462
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

463
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		// 5.) add group, remove group
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		let rightGroup = part.addGroup(part.activeGroup, GroupDirection.RIGHT);
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

		rightGroup.focus();
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(false);

		part.removeGroup(rightGroup);
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(false);

484
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
485 486 487 488 489 490 491 492 493 494 495 496
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		// 6.) open editor in inactive group
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		rightGroup = part.addGroup(part.activeGroup, GroupDirection.RIGHT);
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
497
		await rightGroup.openEditor(otherInput);
498
		assertActiveEditorChangedEvent(true);
B
Benjamin Pasero 已提交
499 500
		assertVisibleEditorsChangedEvent(true);

B
Benjamin Pasero 已提交
501
		await closeEditorAndWaitForNextToOpen(rightGroup, otherInput);
502
		assertActiveEditorChangedEvent(true);
B
Benjamin Pasero 已提交
503 504
		assertVisibleEditorsChangedEvent(true);

505
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
506 507 508 509 510 511 512 513 514 515 516 517
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		// 7.) activate group
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		rightGroup = part.addGroup(part.activeGroup, GroupDirection.RIGHT);
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
518
		await rightGroup.openEditor(otherInput);
519
		assertActiveEditorChangedEvent(true);
B
Benjamin Pasero 已提交
520 521
		assertVisibleEditorsChangedEvent(true);

522
		group.focus();
B
Benjamin Pasero 已提交
523 524 525
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
526
		await closeEditorAndWaitForNextToOpen(rightGroup, otherInput);
527
		assertActiveEditorChangedEvent(false);
B
Benjamin Pasero 已提交
528 529
		assertVisibleEditorsChangedEvent(true);

530
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
531 532 533 534 535 536 537 538 539 540 541 542
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		// 8.) move editor
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		editor = await service.openEditor(otherInput, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

543
		group.moveEditor(otherInput, group, { index: 0 });
B
Benjamin Pasero 已提交
544 545 546
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

547
		await group.closeAllEditors();
B
Benjamin Pasero 已提交
548 549 550
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

551 552 553 554 555 556 557 558 559
		// 9.) close editor in inactive group
		editor = await service.openEditor(input, { pinned: true });
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

		rightGroup = part.addGroup(part.activeGroup, GroupDirection.RIGHT);
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(false);

B
Benjamin Pasero 已提交
560
		await rightGroup.openEditor(otherInput);
561 562 563
		assertActiveEditorChangedEvent(true);
		assertVisibleEditorsChangedEvent(true);

B
Benjamin Pasero 已提交
564
		await closeEditorAndWaitForNextToOpen(group, input);
565 566 567
		assertActiveEditorChangedEvent(false);
		assertVisibleEditorsChangedEvent(true);

B
Benjamin Pasero 已提交
568 569 570 571
		// cleanup
		activeEditorChangeListener.dispose();
		visibleEditorChangeListener.dispose();
	});
572 573 574 575

	test('openEditor returns NULL when opening fails or is inactive', async function () {
		const partInstantiator = workbenchInstantiationService();

576
		const part = partInstantiator.createInstance(EditorPart);
577
		part.create(document.createElement('div'));
578
		part.layout(400, 300);
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599

		const testInstantiationService = partInstantiator.createChild(new ServiceCollection([IEditorGroupsService, part]));

		const service: EditorServiceImpl = testInstantiationService.createInstance(EditorService);

		const input = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource-active'));
		const otherInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource2-inactive'));
		const failingInput = testInstantiationService.createInstance(TestEditorInput, URI.parse('my://resource3-failing'));
		failingInput.setFailToOpen();

		await part.whenRestored;

		let editor = await service.openEditor(input, { pinned: true });
		assert.ok(editor);

		let otherEditor = await service.openEditor(otherInput, { inactive: true });
		assert.ok(!otherEditor);

		let failingEditor = await service.openEditor(failingInput);
		assert.ok(!failingEditor);
	});
600
});