textFileService.test.ts 20.9 KB
Newer Older
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  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';
6
import * as sinon from 'sinon';
D
Daniel Imms 已提交
7
import * as platform from 'vs/base/common/platform';
8
import { URI } from 'vs/base/common/uri';
9
import { ILifecycleService, BeforeShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
10
import { workbenchInstantiationService, TestLifecycleService, TestTextFileService, TestWindowsService, TestContextService, TestFileService } from 'vs/workbench/test/workbenchTestServices';
11
import { toResource } from 'vs/base/test/common/utils';
J
Johannes Rieken 已提交
12
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
13
import { IWindowsService } from 'vs/platform/windows/common/windows';
J
Johannes Rieken 已提交
14 15 16 17 18
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ConfirmResult } from 'vs/workbench/common/editor';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
19
import { HotExitConfiguration, IFileService } from 'vs/platform/files/common/files';
J
Johannes Rieken 已提交
20
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
B
Benjamin Pasero 已提交
21
import { IWorkspaceContextService, Workspace } from 'vs/platform/workspace/common/workspace';
22 23 24
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { Schemas } from 'vs/base/common/network';
25 26 27 28

class ServiceAccessor {
	constructor(
		@ILifecycleService public lifecycleService: TestLifecycleService,
B
Benjamin Pasero 已提交
29
		@ITextFileService public textFileService: TestTextFileService,
30
		@IUntitledEditorService public untitledEditorService: IUntitledEditorService,
D
Daniel Imms 已提交
31
		@IWindowsService public windowsService: TestWindowsService,
32 33 34
		@IWorkspaceContextService public contextService: TestContextService,
		@IModelService public modelService: ModelServiceImpl,
		@IFileService public fileService: TestFileService
35 36 37 38
	) {
	}
}

39
class BeforeShutdownEventImpl implements BeforeShutdownEvent {
40

J
Johannes Rieken 已提交
41
	public value: boolean | Promise<boolean>;
42
	public reason = ShutdownReason.CLOSE;
43

J
Johannes Rieken 已提交
44
	veto(value: boolean | Promise<boolean>): void {
45 46 47 48
		this.value = value;
	}
}

B
renames  
Benjamin Pasero 已提交
49
suite('Files - TextFileService', () => {
50

51
	let instantiationService: IInstantiationService;
52
	let model: TextFileEditorModel;
B
Benjamin Pasero 已提交
53
	let accessor: ServiceAccessor;
54 55

	setup(() => {
B
Benjamin Pasero 已提交
56
		instantiationService = workbenchInstantiationService();
57 58 59 60
		accessor = instantiationService.createInstance(ServiceAccessor);
	});

	teardown(() => {
61 62 63
		if (model) {
			model.dispose();
		}
64
		(<TextFileEditorModelManager>accessor.textFileService.models).clear();
65
		(<TextFileEditorModelManager>accessor.textFileService.models).dispose();
B
Benjamin Pasero 已提交
66
		accessor.untitledEditorService.revertAll();
67 68
	});

D
Daniel Imms 已提交
69
	test('confirm onWillShutdown - no veto', function () {
B
Benjamin Pasero 已提交
70 71 72
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

73
		const event = new BeforeShutdownEventImpl();
74 75
		accessor.lifecycleService.fireWillShutdown(event);

B
Benjamin Pasero 已提交
76 77 78 79 80 81 82 83
		const veto = event.value;
		if (typeof veto === 'boolean') {
			assert.ok(!veto);
		} else {
			veto.then(veto => {
				assert.ok(!veto);
			});
		}
84 85
	});

86
	test('confirm onWillShutdown - veto if user cancels', function () {
B
Benjamin Pasero 已提交
87 88 89
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
90 91
		const service = accessor.textFileService;
		service.setConfirmResult(ConfirmResult.CANCEL);
92

93
		return model.load().then(() => {
94
			model.textEditorModel!.setValue('foo');
95

B
Benjamin Pasero 已提交
96
			assert.equal(service.getDirty().length, 1);
97

98
			const event = new BeforeShutdownEventImpl();
99 100 101
			accessor.lifecycleService.fireWillShutdown(event);

			assert.ok(event.value);
102
		});
103 104
	});

105
	test('confirm onWillShutdown - no veto and backups cleaned up if user does not want to save (hot.exit: off)', function () {
B
Benjamin Pasero 已提交
106 107 108
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
109 110
		const service = accessor.textFileService;
		service.setConfirmResult(ConfirmResult.DONT_SAVE);
111
		service.onFilesConfigurationChange({ files: { hotExit: 'off' } });
112

113
		return model.load().then(() => {
114
			model.textEditorModel!.setValue('foo');
115

B
Benjamin Pasero 已提交
116
			assert.equal(service.getDirty().length, 1);
117

118
			const event = new BeforeShutdownEventImpl();
119 120
			accessor.lifecycleService.fireWillShutdown(event);

B
Benjamin Pasero 已提交
121 122
			const veto = event.value;
			if (typeof veto === 'boolean') {
123
				assert.ok(service.cleanupBackupsBeforeShutdownCalled);
B
Benjamin Pasero 已提交
124
				assert.ok(!veto);
D
Daniel Imms 已提交
125

R
Rob Lourens 已提交
126
				return undefined;
B
Benjamin Pasero 已提交
127
			} else {
128
				return veto.then(veto => {
129
					assert.ok(service.cleanupBackupsBeforeShutdownCalled);
B
Benjamin Pasero 已提交
130 131 132
					assert.ok(!veto);
				});
			}
133
		});
134 135
	});

136
	test('confirm onWillShutdown - save (hot.exit: off)', function () {
B
Benjamin Pasero 已提交
137 138 139
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
140 141
		const service = accessor.textFileService;
		service.setConfirmResult(ConfirmResult.SAVE);
142
		service.onFilesConfigurationChange({ files: { hotExit: 'off' } });
143

144
		return model.load().then(() => {
145
			model.textEditorModel!.setValue('foo');
146

B
Benjamin Pasero 已提交
147
			assert.equal(service.getDirty().length, 1);
148

149
			const event = new BeforeShutdownEventImpl();
150 151
			accessor.lifecycleService.fireWillShutdown(event);

J
Johannes Rieken 已提交
152
			return (<Promise<boolean>>event.value).then(veto => {
153 154 155
				assert.ok(!veto);
				assert.ok(!model.isDirty());
			});
156
		});
157
	});
B
Benjamin Pasero 已提交
158

159
	test('isDirty/getDirty - files and untitled', function () {
B
Benjamin Pasero 已提交
160 161 162
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
163
		const service = accessor.textFileService;
164
		return model.load().then(() => {
B
Benjamin Pasero 已提交
165
			assert.ok(!service.isDirty(model.getResource()));
166
			model.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
167 168 169 170 171 172 173 174 175

			assert.ok(service.isDirty(model.getResource()));
			assert.equal(service.getDirty().length, 1);
			assert.equal(service.getDirty([model.getResource()])[0].toString(), model.getResource().toString());

			const untitled = accessor.untitledEditorService.createOrGet();
			return untitled.resolve().then((model: UntitledEditorModel) => {
				assert.ok(!service.isDirty(untitled.getResource()));
				assert.equal(service.getDirty().length, 1);
176
				model.textEditorModel!.setValue('changed');
B
Benjamin Pasero 已提交
177 178 179 180 181

				assert.ok(service.isDirty(untitled.getResource()));
				assert.equal(service.getDirty().length, 2);
				assert.equal(service.getDirty([untitled.getResource()])[0].toString(), untitled.getResource().toString());
			});
182
		});
B
Benjamin Pasero 已提交
183 184
	});

185
	test('save - file', function () {
B
Benjamin Pasero 已提交
186 187 188
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
189 190
		const service = accessor.textFileService;

191
		return model.load().then(() => {
192
			model.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
193 194 195 196 197 198 199

			assert.ok(service.isDirty(model.getResource()));

			return service.save(model.getResource()).then(res => {
				assert.ok(res);
				assert.ok(!service.isDirty(model.getResource()));
			});
200
		});
B
Benjamin Pasero 已提交
201 202
	});

203 204 205 206 207 208 209
	test('save - UNC path', function () {
		const untitledUncUri = URI.from({ scheme: 'untitled', authority: 'server', path: '/share/path/file.txt' });
		model = instantiationService.createInstance(TextFileEditorModel, untitledUncUri, 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

		const mockedFileUri = untitledUncUri.with({ scheme: Schemas.file });
		const mockedEditorInput = instantiationService.createInstance(TextFileEditorModel, mockedFileUri, 'utf8');
B
Benjamin Pasero 已提交
210
		const loadOrCreateStub = sinon.stub(accessor.textFileService.models, 'loadOrCreate', () => Promise.resolve(mockedEditorInput));
211 212 213 214 215 216

		sinon.stub(accessor.untitledEditorService, 'exists', () => true);
		sinon.stub(accessor.untitledEditorService, 'hasAssociatedFilePath', () => true);
		sinon.stub(accessor.modelService, 'updateModel', () => { });

		return model.load().then(() => {
217
			model.textEditorModel!.setValue('foo');
218 219 220 221 222 223

			return accessor.textFileService.saveAll(true).then(res => {
				assert.ok(loadOrCreateStub.calledOnce);
				assert.equal(res.results.length, 1);
				assert.ok(res.results[0].success);

224 225 226
				assert.equal(res.results[0].target!.scheme, Schemas.file);
				assert.equal(res.results[0].target!.authority, untitledUncUri.authority);
				assert.equal(res.results[0].target!.path, untitledUncUri.path);
227 228 229 230
			});
		});
	});

231
	test('saveAll - file', function () {
B
Benjamin Pasero 已提交
232 233 234
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
235 236
		const service = accessor.textFileService;

237
		return model.load().then(() => {
238
			model.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
239 240 241 242 243 244 245 246 247

			assert.ok(service.isDirty(model.getResource()));

			return service.saveAll([model.getResource()]).then(res => {
				assert.ok(res);
				assert.ok(!service.isDirty(model.getResource()));
				assert.equal(res.results.length, 1);
				assert.equal(res.results[0].source.toString(), model.getResource().toString());
			});
248
		});
B
Benjamin Pasero 已提交
249 250
	});

251
	test('saveAs - file', function () {
B
Benjamin Pasero 已提交
252 253 254
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
255
		const service = accessor.textFileService;
M
Martin Aeschlimann 已提交
256
		service.setPromptPath(model.getResource());
B
Benjamin Pasero 已提交
257

258
		return model.load().then(() => {
259
			model.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
260 261 262 263

			assert.ok(service.isDirty(model.getResource()));

			return service.saveAs(model.getResource()).then(res => {
264
				assert.equal(res!.toString(), model.getResource().toString());
B
Benjamin Pasero 已提交
265 266
				assert.ok(!service.isDirty(model.getResource()));
			});
267
		});
B
Benjamin Pasero 已提交
268 269
	});

270
	test('revert - file', function () {
B
Benjamin Pasero 已提交
271 272 273
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

B
Benjamin Pasero 已提交
274
		const service = accessor.textFileService;
M
Martin Aeschlimann 已提交
275
		service.setPromptPath(model.getResource());
B
Benjamin Pasero 已提交
276

277
		return model.load().then(() => {
278
			model!.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
279 280 281 282 283 284 285

			assert.ok(service.isDirty(model.getResource()));

			return service.revert(model.getResource()).then(res => {
				assert.ok(res);
				assert.ok(!service.isDirty(model.getResource()));
			});
286
		});
B
Benjamin Pasero 已提交
287
	});
288

B
Benjamin Pasero 已提交
289 290 291 292 293 294 295
	test('delete - dirty file', function () {
		model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

		const service = accessor.textFileService;

		return model.load().then(() => {
296
			model!.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

			assert.ok(service.isDirty(model.getResource()));

			return service.delete(model.getResource()).then(() => {
				assert.ok(!service.isDirty(model.getResource()));
			});
		});
	});

	test('move - dirty file', function () {
		let sourceModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
		let targetModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file_target.txt'), 'utf8');
		(<TextFileEditorModelManager>accessor.textFileService.models).add(sourceModel.getResource(), sourceModel);
		(<TextFileEditorModelManager>accessor.textFileService.models).add(targetModel.getResource(), targetModel);

		const service = accessor.textFileService;

		return sourceModel.load().then(() => {
315
			sourceModel.textEditorModel!.setValue('foo');
B
Benjamin Pasero 已提交
316 317 318 319 320 321 322 323 324 325 326 327

			assert.ok(service.isDirty(sourceModel.getResource()));

			return service.move(sourceModel.getResource(), targetModel.getResource(), true).then(() => {
				assert.ok(!service.isDirty(sourceModel.getResource()));

				sourceModel.dispose();
				targetModel.dispose();
			});
		});
	});

328 329
	suite('Hot Exit', () => {
		suite('"onExit" setting', () => {
330 331
			test('should hot exit on non-Mac (reason: CLOSE, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, true, !!platform.isMacintosh);
332
			});
333 334
			test('should hot exit on non-Mac (reason: CLOSE, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, false, false, !!platform.isMacintosh);
D
Daniel Imms 已提交
335
			});
336 337
			test('should NOT hot exit (reason: CLOSE, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, true, true, true);
338
			});
339 340
			test('should NOT hot exit (reason: CLOSE, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.CLOSE, true, false, true);
D
Daniel Imms 已提交
341
			});
342 343
			test('should hot exit (reason: QUIT, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.QUIT, false, true, false);
D
Daniel Imms 已提交
344
			});
345 346
			test('should hot exit (reason: QUIT, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.QUIT, false, false, false);
D
Daniel Imms 已提交
347
			});
348 349
			test('should hot exit (reason: QUIT, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.QUIT, true, true, false);
350
			});
351 352
			test('should hot exit (reason: QUIT, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.QUIT, true, false, false);
D
Daniel Imms 已提交
353
			});
354 355
			test('should hot exit (reason: RELOAD, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.RELOAD, false, true, false);
356
			});
357 358
			test('should hot exit (reason: RELOAD, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.RELOAD, false, false, false);
359
			});
360 361
			test('should hot exit (reason: RELOAD, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.RELOAD, true, true, false);
362
			});
363 364
			test('should hot exit (reason: RELOAD, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.RELOAD, true, false, false);
D
Daniel Imms 已提交
365
			});
366 367
			test('should NOT hot exit (reason: LOAD, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.LOAD, false, true, true);
368
			});
369 370
			test('should NOT hot exit (reason: LOAD, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.LOAD, false, false, true);
D
Daniel Imms 已提交
371
			});
372 373
			test('should NOT hot exit (reason: LOAD, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.LOAD, true, true, true);
374
			});
375 376
			test('should NOT hot exit (reason: LOAD, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT, ShutdownReason.LOAD, true, false, true);
D
Daniel Imms 已提交
377
			});
378 379 380
		});

		suite('"onExitAndWindowClose" setting', () => {
381 382
			test('should hot exit (reason: CLOSE, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, false, true, false);
D
Daniel Imms 已提交
383
			});
384 385
			test('should hot exit (reason: CLOSE, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, false, false, !!platform.isMacintosh);
386
			});
387 388
			test('should hot exit (reason: CLOSE, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, true, true, false);
389
			});
390 391
			test('should NOT hot exit (reason: CLOSE, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.CLOSE, true, false, true);
D
Daniel Imms 已提交
392
			});
393 394
			test('should hot exit (reason: QUIT, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.QUIT, false, true, false);
395
			});
396 397
			test('should hot exit (reason: QUIT, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.QUIT, false, false, false);
D
Daniel Imms 已提交
398
			});
399 400
			test('should hot exit (reason: QUIT, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.QUIT, true, true, false);
D
Daniel Imms 已提交
401
			});
402 403
			test('should hot exit (reason: QUIT, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.QUIT, true, false, false);
404
			});
405 406
			test('should hot exit (reason: RELOAD, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.RELOAD, false, true, false);
407
			});
408 409
			test('should hot exit (reason: RELOAD, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.RELOAD, false, false, false);
D
Daniel Imms 已提交
410
			});
411 412
			test('should hot exit (reason: RELOAD, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.RELOAD, true, true, false);
D
Daniel Imms 已提交
413
			});
414 415
			test('should hot exit (reason: RELOAD, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.RELOAD, true, false, false);
416
			});
417 418
			test('should hot exit (reason: LOAD, windows: single, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.LOAD, false, true, false);
419
			});
420 421
			test('should NOT hot exit (reason: LOAD, windows: single, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.LOAD, false, false, true);
D
Daniel Imms 已提交
422
			});
423 424
			test('should hot exit (reason: LOAD, windows: multiple, workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.LOAD, true, true, false);
425
			});
426 427
			test('should NOT hot exit (reason: LOAD, windows: multiple, empty workspace)', function () {
				return hotExitTest.call(this, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE, ShutdownReason.LOAD, true, false, true);
D
Daniel Imms 已提交
428
			});
429 430
		});

J
Johannes Rieken 已提交
431
		function hotExitTest(this: any, setting: string, shutdownReason: ShutdownReason, multipleWindows: boolean, workspace: true, shouldVeto: boolean): Promise<void> {
432 433 434 435
			model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8');
			(<TextFileEditorModelManager>accessor.textFileService.models).add(model.getResource(), model);

			const service = accessor.textFileService;
436
			// Set hot exit config
437
			service.onFilesConfigurationChange({ files: { hotExit: setting } });
438 439
			// Set empty workspace if required
			if (!workspace) {
B
Benjamin Pasero 已提交
440
				accessor.contextService.setWorkspace(new Workspace('empty:1508317022751'));
441 442 443 444 445 446
			}
			// Set multiple windows if required
			if (multipleWindows) {
				accessor.windowsService.windowCount = 2;
			}
			// Set cancel to force a veto if hot exit does not trigger
447
			service.setConfirmResult(ConfirmResult.CANCEL);
448

449
			return model.load().then(() => {
450
				model.textEditorModel!.setValue('foo');
451 452 453

				assert.equal(service.getDirty().length, 1);

454
				const event = new BeforeShutdownEventImpl();
455
				event.reason = shutdownReason;
456 457
				accessor.lifecycleService.fireWillShutdown(event);

J
Johannes Rieken 已提交
458
				return (<Promise<boolean>>event.value).then(veto => {
459 460 461
					// When hot exit is set, backups should never be cleaned since the confirm result is cancel
					assert.ok(!service.cleanupBackupsBeforeShutdownCalled);
					assert.equal(veto, shouldVeto);
462
				});
463
			});
464 465
		}
	});
466
});