backupMainService.test.ts 23.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  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';
import * as platform from 'vs/base/common/platform';
D
Daniel Imms 已提交
10
import fs = require('fs');
11 12 13 14 15
import os = require('os');
import path = require('path');
import extfs = require('vs/base/node/extfs');
import pfs = require('vs/base/node/pfs');
import Uri from 'vs/base/common/uri';
16 17
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { parseArgs } from 'vs/platform/environment/node/argv';
D
Daniel Imms 已提交
18
import { BackupMainService } from 'vs/platform/backup/electron-main/backupMainService';
19
import { IBackupWorkspacesFormat } from 'vs/platform/backup/common/backup';
20 21
import { HotExitConfiguration } from 'vs/platform/files/common/files';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
B
Benjamin Pasero 已提交
22
import { LogMainService } from "vs/platform/log/common/log";
23

D
Daniel Imms 已提交
24
class TestBackupMainService extends BackupMainService {
B
Benjamin Pasero 已提交
25

26
	constructor(backupHome: string, backupWorkspacesPath: string, configService: TestConfigurationService) {
B
Benjamin Pasero 已提交
27
		super(new EnvironmentService(parseArgs(process.argv), process.execPath), configService, new LogMainService(new EnvironmentService(parseArgs(process.argv), process.execPath)));
28 29

		this.backupHome = backupHome;
D
Daniel Imms 已提交
30
		this.workspacesJsonPath = backupWorkspacesPath;
31 32 33

		// Force a reload with the new paths
		this.loadSync();
34
	}
35

36 37 38 39 40 41
	public get backupsData(): IBackupWorkspacesFormat {
		return this.backups;
	}

	public removeBackupPathSync(workspaceIdenfitier: string, target: string[]): void {
		return super.removeBackupPathSync(workspaceIdenfitier, target);
42 43 44 45 46 47
	}

	public loadSync(): void {
		super.loadSync();
	}

48 49
	public dedupeBackups(backups: IBackupWorkspacesFormat): IBackupWorkspacesFormat {
		return super.dedupeBackups(backups);
D
Daniel Imms 已提交
50 51
	}

52
	public toBackupPath(workspacePath: string): string {
D
Daniel Imms 已提交
53
		return path.join(this.backupHome, super.getWorkspaceHash(workspacePath));
54
	}
55 56 57 58

	public getWorkspaceHash(workspacePath: string): string {
		return super.getWorkspaceHash(workspacePath);
	}
59 60
}

D
Daniel Imms 已提交
61
suite('BackupMainService', () => {
D
Daniel Imms 已提交
62
	const parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
63 64 65 66 67 68
	const backupHome = path.join(parentDir, 'Backups');
	const backupWorkspacesPath = path.join(backupHome, 'workspaces.json');

	const fooFile = Uri.file(platform.isWindows ? 'C:\\foo' : '/foo');
	const barFile = Uri.file(platform.isWindows ? 'C:\\bar' : '/bar');

69
	let service: TestBackupMainService;
70
	let configService: TestConfigurationService;
71 72

	setup(done => {
73 74
		configService = new TestConfigurationService();
		service = new TestBackupMainService(backupHome, backupWorkspacesPath, configService);
75 76 77 78

		// Delete any existing backups completely and then re-create it.
		extfs.del(backupHome, os.tmpdir(), () => {
			pfs.mkdirp(backupHome).then(() => {
D
Daniel Imms 已提交
79
				done();
80 81 82 83 84 85 86 87
			});
		});
	});

	teardown(done => {
		extfs.del(backupHome, os.tmpdir(), done);
	});

88
	test('service validates backup workspaces on startup and cleans up (folder workspaces)', done => {
89

90
		// 1) backup workspace path does not exist
B
Benjamin Pasero 已提交
91 92
		service.registerFolderBackupSync(fooFile.fsPath);
		service.registerFolderBackupSync(barFile.fsPath);
93
		service.loadSync();
94
		assert.deepEqual(service.getFolderBackupPaths(), []);
95 96 97 98

		// 2) backup workspace path exists with empty contents within
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
B
Benjamin Pasero 已提交
99 100
		service.registerFolderBackupSync(fooFile.fsPath);
		service.registerFolderBackupSync(barFile.fsPath);
101
		service.loadSync();
102
		assert.deepEqual(service.getFolderBackupPaths(), []);
103 104 105 106 107 108 109 110
		assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath)));
		assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath)));

		// 3) backup workspace path exists with empty folders within
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
		fs.mkdirSync(path.join(service.toBackupPath(fooFile.fsPath), 'file'));
		fs.mkdirSync(path.join(service.toBackupPath(barFile.fsPath), 'untitled'));
B
Benjamin Pasero 已提交
111 112
		service.registerFolderBackupSync(fooFile.fsPath);
		service.registerFolderBackupSync(barFile.fsPath);
113
		service.loadSync();
114
		assert.deepEqual(service.getFolderBackupPaths(), []);
115 116 117
		assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath)));
		assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath)));

118 119 120 121 122 123
		// 4) backup workspace path points to a workspace that no longer exists
		// so it should convert the backup worspace to an empty workspace backup
		const fileBackups = path.join(service.toBackupPath(fooFile.fsPath), 'file');
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
		fs.mkdirSync(fileBackups);
B
Benjamin Pasero 已提交
124
		service.registerFolderBackupSync(fooFile.fsPath);
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
		assert.equal(service.getFolderBackupPaths().length, 1);
		assert.equal(service.getEmptyWindowBackupPaths().length, 0);
		fs.writeFileSync(path.join(fileBackups, 'backup.txt'), '');
		service.loadSync();
		assert.equal(service.getFolderBackupPaths().length, 0);
		assert.equal(service.getEmptyWindowBackupPaths().length, 1);

		done();
	});

	test('service validates backup workspaces on startup and cleans up (root workspaces)', done => {

		// 1) backup workspace path does not exist
		service.registerWorkspaceBackupSync(fooFile.fsPath);
		service.registerWorkspaceBackupSync(barFile.fsPath);
		service.loadSync();
		assert.deepEqual(service.getWorkspaceBackupPaths(), []);

		// 2) backup workspace path exists with empty contents within
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
		service.registerWorkspaceBackupSync(fooFile.fsPath);
		service.registerWorkspaceBackupSync(barFile.fsPath);
		service.loadSync();
		assert.deepEqual(service.getWorkspaceBackupPaths(), []);
		assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath)));
		assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath)));

		// 3) backup workspace path exists with empty folders within
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
		fs.mkdirSync(path.join(service.toBackupPath(fooFile.fsPath), 'file'));
		fs.mkdirSync(path.join(service.toBackupPath(barFile.fsPath), 'untitled'));
		service.registerWorkspaceBackupSync(fooFile.fsPath);
		service.registerWorkspaceBackupSync(barFile.fsPath);
		service.loadSync();
		assert.deepEqual(service.getWorkspaceBackupPaths(), []);
		assert.ok(!fs.exists(service.toBackupPath(fooFile.fsPath)));
		assert.ok(!fs.exists(service.toBackupPath(barFile.fsPath)));

		// 4) backup workspace path points to a workspace that no longer exists
		// so it should convert the backup worspace to an empty workspace backup
		const fileBackups = path.join(service.toBackupPath(fooFile.fsPath), 'file');
		fs.mkdirSync(service.toBackupPath(fooFile.fsPath));
		fs.mkdirSync(service.toBackupPath(barFile.fsPath));
		fs.mkdirSync(fileBackups);
		service.registerWorkspaceBackupSync(fooFile.fsPath);
172
		assert.equal(service.getWorkspaceBackupPaths().length, 1);
173
		assert.equal(service.getEmptyWindowBackupPaths().length, 0);
174 175
		fs.writeFileSync(path.join(fileBackups, 'backup.txt'), '');
		service.loadSync();
176
		assert.equal(service.getWorkspaceBackupPaths().length, 0);
177
		assert.equal(service.getEmptyWindowBackupPaths().length, 1);
178

179 180 181
		done();
	});

182
	suite('loadSync', () => {
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
		test('getFolderBackupPaths() should return [] when workspaces.json doesn\'t exist', () => {
			assert.deepEqual(service.getFolderBackupPaths(), []);
		});

		test('getFolderBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => {
			fs.writeFileSync(backupWorkspacesPath, '');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{]');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, 'foo');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
		});

		test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => {
			fs.writeFileSync(backupWorkspacesPath, '{}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
		});

		test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', () => {
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{}}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": ["bar"]}}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": []}}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": "bar"}}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":"foo"}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
			fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":1}');
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
		});

		test('getFolderBackupPaths() should return [] when files.hotExit = "onExitAndWindowClose"', () => {
			service.registerFolderBackupSync(fooFile.fsPath.toUpperCase());
			assert.deepEqual(service.getFolderBackupPaths(), [fooFile.fsPath.toUpperCase()]);
			configService.setUserConfiguration('files.hotExit', HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE);
			service.loadSync();
			assert.deepEqual(service.getFolderBackupPaths(), []);
		});

234 235
		test('getWorkspaceBackupPaths() should return [] when workspaces.json doesn\'t exist', () => {
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
236
		});
D
Daniel Imms 已提交
237

238
		test('getWorkspaceBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => {
239 240
			fs.writeFileSync(backupWorkspacesPath, '');
			service.loadSync();
241
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
242 243
			fs.writeFileSync(backupWorkspacesPath, '{]');
			service.loadSync();
244
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
245 246
			fs.writeFileSync(backupWorkspacesPath, 'foo');
			service.loadSync();
247
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
248
		});
D
Daniel Imms 已提交
249

250
		test('getWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => {
251 252
			fs.writeFileSync(backupWorkspacesPath, '{}');
			service.loadSync();
253
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
254 255
		});

256 257
		test('getWorkspaceBackupPaths() should return [] when rootWorkspaces in workspaces.json is not a string array', () => {
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{}}');
258
			service.loadSync();
259
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
260
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": ["bar"]}}');
261
			service.loadSync();
262
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
263
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": []}}');
264
			service.loadSync();
265
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
266
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": "bar"}}');
267
			service.loadSync();
268
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
269
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":"foo"}');
270
			service.loadSync();
271
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
272
			fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":1}');
273
			service.loadSync();
274
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
275
		});
D
Daniel Imms 已提交
276

277
		test('getWorkspaceBackupPaths() should return [] when files.hotExit = "onExitAndWindowClose"', () => {
278
			service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase());
279 280 281 282 283 284
			assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath.toUpperCase()]);
			configService.setUserConfiguration('files.hotExit', HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE);
			service.loadSync();
			assert.deepEqual(service.getWorkspaceBackupPaths(), []);
		});

285
		test('getEmptyWorkspaceBackupPaths() should return [] when workspaces.json doesn\'t exist', () => {
286
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
287 288
		});

289
		test('getEmptyWorkspaceBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => {
290 291
			fs.writeFileSync(backupWorkspacesPath, '');
			service.loadSync();
292
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
293 294
			fs.writeFileSync(backupWorkspacesPath, '{]');
			service.loadSync();
295
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
296 297
			fs.writeFileSync(backupWorkspacesPath, 'foo');
			service.loadSync();
298
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
299 300
		});

301
		test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => {
302 303
			fs.writeFileSync(backupWorkspacesPath, '{}');
			service.loadSync();
304
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
305 306
		});

307
		test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', () => {
308 309
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{}}');
			service.loadSync();
310
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
311 312
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": ["bar"]}}');
			service.loadSync();
313
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
314 315
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": []}}');
			service.loadSync();
316
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
317 318
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": "bar"}}');
			service.loadSync();
319
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
320 321
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":"foo"}');
			service.loadSync();
322
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
323 324
			fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":1}');
			service.loadSync();
325
			assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
326
		});
D
Daniel Imms 已提交
327
	});
328

329
	suite('dedupeFolderWorkspaces', () => {
330
		test('should ignore duplicates on Windows and Mac (folder workspace)', () => {
331 332 333 334 335
			// Skip test on Linux
			if (platform.isLinux) {
				return;
			}

D
Daniel Imms 已提交
336
			const backups: IBackupWorkspacesFormat = {
337
				rootWorkspaces: [],
338
				folderWorkspaces: platform.isWindows ? ['c:\\FOO', 'C:\\FOO', 'c:\\foo'] : ['/FOO', '/foo'],
D
Daniel Imms 已提交
339 340 341
				emptyWorkspaces: []
			};

342
			service.dedupeBackups(backups);
343

344
			assert.equal(backups.folderWorkspaces.length, 1);
345
			if (platform.isWindows) {
346
				assert.deepEqual(backups.folderWorkspaces, ['c:\\FOO'], 'should return the first duplicated entry');
D
Daniel Imms 已提交
347
			} else {
348
				assert.deepEqual(backups.folderWorkspaces, ['/FOO'], 'should return the first duplicated entry');
349 350
			}
		});
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372

		test('should ignore duplicates on Windows and Mac (root workspace)', () => {
			// Skip test on Linux
			if (platform.isLinux) {
				return;
			}

			const backups: IBackupWorkspacesFormat = {
				rootWorkspaces: platform.isWindows ? ['c:\\FOO', 'C:\\FOO', 'c:\\foo'] : ['/FOO', '/foo'],
				folderWorkspaces: [],
				emptyWorkspaces: []
			};

			service.dedupeBackups(backups);

			assert.equal(backups.rootWorkspaces.length, 1);
			if (platform.isWindows) {
				assert.deepEqual(backups.rootWorkspaces, ['c:\\FOO'], 'should return the first duplicated entry');
			} else {
				assert.deepEqual(backups.rootWorkspaces, ['/FOO'], 'should return the first duplicated entry');
			}
		});
D
Daniel Imms 已提交
373 374
	});

375
	suite('registerWindowForBackups', () => {
376
		test('should persist paths to workspaces.json (folder workspace)', done => {
B
Benjamin Pasero 已提交
377 378
			service.registerFolderBackupSync(fooFile.fsPath);
			service.registerFolderBackupSync(barFile.fsPath);
379
			assert.deepEqual(service.getFolderBackupPaths(), [fooFile.fsPath, barFile.fsPath]);
380 381 382
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.folderWorkspaces, [fooFile.fsPath, barFile.fsPath]);
D
Daniel Imms 已提交
383
				done();
384 385
			});
		});
D
Daniel Imms 已提交
386

387 388 389 390 391 392 393 394 395 396 397 398
		test('should persist paths to workspaces.json (root workspace)', done => {
			service.registerWorkspaceBackupSync(fooFile.fsPath);
			service.registerWorkspaceBackupSync(barFile.fsPath);
			assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath, barFile.fsPath]);
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.rootWorkspaces, [fooFile.fsPath, barFile.fsPath]);
				done();
			});
		});

		test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (folder workspace)', done => {
B
Benjamin Pasero 已提交
399
			service.registerFolderBackupSync(fooFile.fsPath.toUpperCase());
400
			assert.deepEqual(service.getFolderBackupPaths(), [fooFile.fsPath.toUpperCase()]);
D
Daniel Imms 已提交
401 402 403 404 405 406
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.folderWorkspaces, [fooFile.fsPath.toUpperCase()]);
				done();
			});
		});
407 408 409 410 411 412 413 414 415 416

		test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (root workspace)', done => {
			service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase());
			assert.deepEqual(service.getWorkspaceBackupPaths(), [fooFile.fsPath.toUpperCase()]);
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.rootWorkspaces, [fooFile.fsPath.toUpperCase()]);
				done();
			});
		});
417 418
	});

419
	suite('removeBackupPathSync', () => {
420
		test('should remove folder workspaces from workspaces.json (folder workspace)', done => {
B
Benjamin Pasero 已提交
421 422
			service.registerFolderBackupSync(fooFile.fsPath);
			service.registerFolderBackupSync(barFile.fsPath);
423
			service.removeBackupPathSync(fooFile.fsPath, service.backupsData.folderWorkspaces);
424 425 426
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.folderWorkspaces, [barFile.fsPath]);
427
				service.removeBackupPathSync(barFile.fsPath, service.backupsData.folderWorkspaces);
428 429 430 431 432
				pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
					const json2 = <IBackupWorkspacesFormat>JSON.parse(content);
					assert.deepEqual(json2.folderWorkspaces, []);
					done();
				});
433 434
			});
		});
435

436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
		test('should remove folder workspaces from workspaces.json (root workspace)', done => {
			service.registerWorkspaceBackupSync(fooFile.fsPath);
			service.registerWorkspaceBackupSync(barFile.fsPath);
			service.removeBackupPathSync(fooFile.fsPath, service.backupsData.rootWorkspaces);
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.rootWorkspaces, [barFile.fsPath]);
				service.removeBackupPathSync(barFile.fsPath, service.backupsData.rootWorkspaces);
				pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
					const json2 = <IBackupWorkspacesFormat>JSON.parse(content);
					assert.deepEqual(json2.rootWorkspaces, []);
					done();
				});
			});
		});

D
Daniel Imms 已提交
452
		test('should remove empty workspaces from workspaces.json', done => {
B
Benjamin Pasero 已提交
453 454
			service.registerEmptyWindowBackupSync('foo');
			service.registerEmptyWindowBackupSync('bar');
455
			service.removeBackupPathSync('foo', service.backupsData.emptyWorkspaces);
D
Daniel Imms 已提交
456 457 458
			pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
				const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
				assert.deepEqual(json.emptyWorkspaces, ['bar']);
459
				service.removeBackupPathSync('bar', service.backupsData.emptyWorkspaces);
D
Daniel Imms 已提交
460 461 462 463 464 465 466 467
				pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
					const json2 = <IBackupWorkspacesFormat>JSON.parse(content);
					assert.deepEqual(json2.emptyWorkspaces, []);
					done();
				});
			});
		});

468
		test('should fail gracefully when removing a path that doesn\'t exist', done => {
469
			const workspacesJson: IBackupWorkspacesFormat = { rootWorkspaces: [], folderWorkspaces: [fooFile.fsPath], emptyWorkspaces: [] };
470
			pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
471 472
				service.removeBackupPathSync(barFile.fsPath, service.backupsData.folderWorkspaces);
				service.removeBackupPathSync('test', service.backupsData.emptyWorkspaces);
473 474 475 476 477 478 479
				pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
					const json = <IBackupWorkspacesFormat>JSON.parse(content);
					assert.deepEqual(json.folderWorkspaces, [fooFile.fsPath]);
					done();
				});
			});
		});
480
	});
D
Daniel Imms 已提交
481

482
	suite('getWorkspaceHash', () => {
D
Daniel Imms 已提交
483 484 485 486
		test('should perform an md5 hash on the path', () => {
			assert.equal(service.getWorkspaceHash('/foo'), '1effb2475fcfba4f9e8b8a1dbc8f3caf');
		});

487 488 489 490 491
		test('should ignore case on Windows and Mac', () => {
			// Skip test on Linux
			if (platform.isLinux) {
				return;
			}
D
Daniel Imms 已提交
492

493 494 495
			if (platform.isMacintosh) {
				assert.equal(service.getWorkspaceHash('/foo'), service.getWorkspaceHash('/FOO'));
			}
D
Daniel Imms 已提交
496

497 498 499 500
			if (platform.isWindows) {
				assert.equal(service.getWorkspaceHash('c:\\foo'), service.getWorkspaceHash('C:\\FOO'));
			}
		});
D
Daniel Imms 已提交
501
	});
502

503
	suite('mixed path casing', () => {
504
		test('should handle case insensitive paths properly (registerWindowForBackupsSync) (folder workspace)', done => {
B
Benjamin Pasero 已提交
505 506
			service.registerFolderBackupSync(fooFile.fsPath);
			service.registerFolderBackupSync(fooFile.fsPath.toUpperCase());
507

508 509 510 511 512 513 514 515 516 517 518 519 520
			if (platform.isLinux) {
				assert.equal(service.getFolderBackupPaths().length, 2);
			} else {
				assert.equal(service.getFolderBackupPaths().length, 1);
			}

			done();
		});

		test('should handle case insensitive paths properly (registerWindowForBackupsSync) (root workspace)', done => {
			service.registerWorkspaceBackupSync(fooFile.fsPath);
			service.registerWorkspaceBackupSync(fooFile.fsPath.toUpperCase());

521 522 523 524 525 526 527 528 529
			if (platform.isLinux) {
				assert.equal(service.getWorkspaceBackupPaths().length, 2);
			} else {
				assert.equal(service.getWorkspaceBackupPaths().length, 1);
			}

			done();
		});

530
		test('should handle case insensitive paths properly (removeBackupPathSync) (folder workspace)', done => {
531 532

			// same case
B
Benjamin Pasero 已提交
533
			service.registerFolderBackupSync(fooFile.fsPath);
534 535
			service.removeBackupPathSync(fooFile.fsPath, service.backupsData.folderWorkspaces);
			assert.equal(service.getFolderBackupPaths().length, 0);
536 537

			// mixed case
B
Benjamin Pasero 已提交
538
			service.registerFolderBackupSync(fooFile.fsPath);
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
			service.removeBackupPathSync(fooFile.fsPath.toUpperCase(), service.backupsData.folderWorkspaces);

			if (platform.isLinux) {
				assert.equal(service.getFolderBackupPaths().length, 1);
			} else {
				assert.equal(service.getFolderBackupPaths().length, 0);
			}

			done();
		});

		test('should handle case insensitive paths properly (removeBackupPathSync) (root workspace)', done => {

			// same case
			service.registerWorkspaceBackupSync(fooFile.fsPath);
			service.removeBackupPathSync(fooFile.fsPath, service.backupsData.rootWorkspaces);
			assert.equal(service.getWorkspaceBackupPaths().length, 0);

			// mixed case
			service.registerWorkspaceBackupSync(fooFile.fsPath);
			service.removeBackupPathSync(fooFile.fsPath.toUpperCase(), service.backupsData.rootWorkspaces);
560 561 562 563 564 565 566 567 568 569

			if (platform.isLinux) {
				assert.equal(service.getWorkspaceBackupPaths().length, 1);
			} else {
				assert.equal(service.getWorkspaceBackupPaths().length, 0);
			}

			done();
		});
	});
570
});