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 95
			model.textEditorModel.setValue('foo');

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 115
			model.textEditorModel.setValue('foo');

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 146
			model.textEditorModel.setValue('foo');

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 166 167 168 169 170 171 172 173 174 175
			assert.ok(!service.isDirty(model.getResource()));
			model.textEditorModel.setValue('foo');

			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(() => {
B
Benjamin Pasero 已提交
192 193 194 195 196 197 198 199
			model.textEditorModel.setValue('foo');

			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 217 218 219 220 221 222 223

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

		return model.load().then(() => {
			model.textEditorModel.setValue('foo');

			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(() => {
B
Benjamin Pasero 已提交
238 239 240 241 242 243 244 245 246 247
			model.textEditorModel.setValue('foo');

			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(() => {
B
Benjamin Pasero 已提交
259 260 261 262 263 264 265 266
			model.textEditorModel.setValue('foo');

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

			return service.saveAs(model.getResource()).then(res => {
				assert.equal(res.toString(), model.getResource().toString());
				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(() => {
B
Benjamin Pasero 已提交
278 279 280 281 282 283 284 285
			model.textEditorModel.setValue('foo');

			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 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
	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(() => {
			model.textEditorModel.setValue('foo');

			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(() => {
			sourceModel.textEditorModel.setValue('foo');

			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 451 452 453
				model.textEditorModel.setValue('foo');

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