fileService.test.ts 26.9 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8 9 10 11 12
/*---------------------------------------------------------------------------------------------
 *  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 fs = require('fs');
import path = require('path');
import os = require('os');
import assert = require('assert');

J
Johannes Rieken 已提交
13 14
import { TPromise } from 'vs/base/common/winjs.base';
import { FileService, IEncodingOverride } from 'vs/workbench/services/files/node/fileService';
15
import { FileOperation, FileOperationEvent, FileChangesEvent, FileOperationResult, IFileOperationResult } from 'vs/platform/files/common/files';
E
Erich Gamma 已提交
16 17 18
import uri from 'vs/base/common/uri';
import uuid = require('vs/base/common/uuid');
import extfs = require('vs/base/node/extfs');
B
Benjamin Pasero 已提交
19
import encodingLib = require('vs/base/node/encoding');
E
Erich Gamma 已提交
20
import utils = require('vs/workbench/services/files/test/node/utils');
21
import { onError } from 'vs/base/test/common/utils';
D
Daniel Imms 已提交
22
import { TestContextService } from "vs/workbench/test/workbenchTestServices";
B
Benjamin Pasero 已提交
23
import { Workspace } from "vs/platform/workspace/common/workspace";
B
Benjamin Pasero 已提交
24

E
Erich Gamma 已提交
25 26 27 28 29
suite('FileService', () => {
	let service: FileService;
	let parentDir = path.join(os.tmpdir(), 'vsctests', 'service');
	let testDir: string;

B
Benjamin Pasero 已提交
30
	setup(function (done) {
E
Erich Gamma 已提交
31 32 33 34
		let id = uuid.generateUuid();
		testDir = path.join(parentDir, id);
		let sourceDir = require.toUrl('./fixtures/service');

35 36 37 38 39
		extfs.copy(sourceDir, testDir, (error) => {
			if (error) {
				return onError(error, done);
			}

B
Benjamin Pasero 已提交
40
			service = new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), { disableWatcher: true });
E
Erich Gamma 已提交
41 42 43 44 45 46 47 48 49
			done();
		});
	});

	teardown((done) => {
		service.dispose();
		extfs.del(parentDir, os.tmpdir(), () => { }, done);
	});

B
Benjamin Pasero 已提交
50
	test('resolveContents', function (done: () => void) {
E
Erich Gamma 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63
		service.resolveContents([
			uri.file(path.join(testDir, 'index.html')),
			uri.file(path.join(testDir, '404.html')),
			uri.file(path.join(testDir, 'deep', 'company.js')),
		]).done(r => {
			assert.equal(r.length, 2);
			assert.equal(r.some(c => c.name === 'index.html'), true);
			assert.equal(r.some(c => c.name === 'company.js'), true);

			done();
		});
	});

B
Benjamin Pasero 已提交
64
	test('createFile', function (done: () => void) {
65 66 67 68 69 70 71 72
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const contents = 'Hello World';
		const resource = uri.file(path.join(testDir, 'test.txt'));
		service.createFile(resource, contents).done(s => {
E
Erich Gamma 已提交
73 74 75 76
			assert.equal(s.name, 'test.txt');
			assert.equal(fs.existsSync(s.resource.fsPath), true);
			assert.equal(fs.readFileSync(s.resource.fsPath), contents);

77 78 79 80 81 82
			assert.ok(event);
			assert.equal(event.resource.fsPath, resource.fsPath);
			assert.equal(event.operation, FileOperation.CREATE);
			assert.equal(event.target.resource.fsPath, resource.fsPath);
			toDispose.dispose();

E
Erich Gamma 已提交
83
			done();
B
Benjamin Pasero 已提交
84
		}, error => onError(error, done));
E
Erich Gamma 已提交
85 86
	});

B
Benjamin Pasero 已提交
87
	test('createFolder', function (done: () => void) {
88 89 90 91 92
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

E
Erich Gamma 已提交
93
		service.resolveFile(uri.file(testDir)).done(parent => {
94 95 96
			const resource = uri.file(path.join(parent.resource.fsPath, 'newFolder'));

			return service.createFolder(resource).then(f => {
E
Erich Gamma 已提交
97 98 99
				assert.equal(f.name, 'newFolder');
				assert.equal(fs.existsSync(f.resource.fsPath), true);

100 101 102 103 104 105 106
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.CREATE);
				assert.equal(event.target.resource.fsPath, resource.fsPath);
				assert.equal(event.target.isDirectory, true);
				toDispose.dispose();

E
Erich Gamma 已提交
107 108
				done();
			});
B
Benjamin Pasero 已提交
109
		}, error => onError(error, done));
E
Erich Gamma 已提交
110 111
	});

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	test('touchFile', function (done: () => void) {
		service.touchFile(uri.file(path.join(testDir, 'test.txt'))).done(s => {
			assert.equal(s.name, 'test.txt');
			assert.equal(fs.existsSync(s.resource.fsPath), true);
			assert.equal(fs.readFileSync(s.resource.fsPath).length, 0);

			const stat = fs.statSync(s.resource.fsPath);

			return TPromise.timeout(10).then(() => {
				return service.touchFile(s.resource).done(s => {
					const statNow = fs.statSync(s.resource.fsPath);
					assert.ok(statNow.mtime.getTime() >= stat.mtime.getTime()); // one some OS the resolution seems to be 1s, so we use >= here
					assert.equal(statNow.size, stat.size);

					done();
				});
			});
B
Benjamin Pasero 已提交
129
		}, error => onError(error, done));
130 131
	});

B
Benjamin Pasero 已提交
132
	test('renameFile', function (done: () => void) {
133 134 135 136 137 138 139
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'index.html'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
140 141 142 143
			return service.rename(source.resource, 'other.html').then(renamed => {
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.equal(fs.existsSync(source.resource.fsPath), false);

144 145 146 147 148 149
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.MOVE);
				assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
150 151
				done();
			});
B
Benjamin Pasero 已提交
152
		}, error => onError(error, done));
E
Erich Gamma 已提交
153 154
	});

B
Benjamin Pasero 已提交
155
	test('renameFolder', function (done: () => void) {
156 157 158 159 160 161 162
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'deep'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
163 164 165 166
			return service.rename(source.resource, 'deeper').then(renamed => {
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.equal(fs.existsSync(source.resource.fsPath), false);

167 168 169 170 171 172
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.MOVE);
				assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
173 174 175 176 177
				done();
			});
		});
	});

B
Benjamin Pasero 已提交
178
	test('renameFile - MIX CASE', function (done: () => void) {
179 180 181 182 183 184 185
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'index.html'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
186 187 188 189
			return service.rename(source.resource, 'INDEX.html').then(renamed => {
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.equal(path.basename(renamed.resource.fsPath), 'INDEX.html');

190 191 192 193 194 195
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.MOVE);
				assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
196 197
				done();
			});
B
Benjamin Pasero 已提交
198
		}, error => onError(error, done));
E
Erich Gamma 已提交
199 200
	});

B
Benjamin Pasero 已提交
201
	test('moveFile', function (done: () => void) {
202 203 204 205 206 207 208
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'index.html'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
209 210 211 212
			return service.moveFile(source.resource, uri.file(path.join(testDir, 'other.html'))).then(renamed => {
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.equal(fs.existsSync(source.resource.fsPath), false);

213 214 215 216 217 218
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.MOVE);
				assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
219 220
				done();
			});
B
Benjamin Pasero 已提交
221
		}, error => onError(error, done));
E
Erich Gamma 已提交
222 223
	});

B
Benjamin Pasero 已提交
224
	test('move - FILE_MOVE_CONFLICT', function (done: () => void) {
225 226 227 228 229
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

E
Erich Gamma 已提交
230
		service.resolveFile(uri.file(path.join(testDir, 'index.html'))).done(source => {
231
			return service.moveFile(source.resource, uri.file(path.join(testDir, 'binary.txt'))).then(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
232 233
				assert.equal(e.fileOperationResult, FileOperationResult.FILE_MOVE_CONFLICT);

234 235 236
				assert.ok(!event);
				toDispose.dispose();

E
Erich Gamma 已提交
237 238
				done();
			});
B
Benjamin Pasero 已提交
239
		}, error => onError(error, done));
E
Erich Gamma 已提交
240 241
	});

B
Benjamin Pasero 已提交
242
	test('moveFile - MIX CASE', function (done: () => void) {
243 244 245 246 247 248 249
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'index.html'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
250 251 252 253
			return service.moveFile(source.resource, uri.file(path.join(testDir, 'INDEX.html'))).then(renamed => {
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.equal(path.basename(renamed.resource.fsPath), 'INDEX.html');

254 255 256 257 258 259
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.MOVE);
				assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
260 261
				done();
			});
B
Benjamin Pasero 已提交
262
		}, error => onError(error, done));
E
Erich Gamma 已提交
263 264
	});

B
Benjamin Pasero 已提交
265
	test('moveFile - overwrite folder with file', function (done: () => void) {
266 267 268 269 270 271 272 273 274 275 276 277 278
		let createEvent: FileOperationEvent;
		let moveEvent: FileOperationEvent;
		let deleteEvent: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			if (e.operation === FileOperation.CREATE) {
				createEvent = e;
			} else if (e.operation === FileOperation.DELETE) {
				deleteEvent = e;
			} else if (e.operation === FileOperation.MOVE) {
				moveEvent = e;
			}
		});

E
Erich Gamma 已提交
279
		service.resolveFile(uri.file(testDir)).done(parent => {
280 281 282 283
			const folderResource = uri.file(path.join(parent.resource.fsPath, 'conway.js'));
			return service.createFolder(folderResource).then(f => {
				const resource = uri.file(path.join(testDir, 'deep', 'conway.js'));
				return service.moveFile(resource, f.resource, true).then(moved => {
E
Erich Gamma 已提交
284 285 286
					assert.equal(fs.existsSync(moved.resource.fsPath), true);
					assert.ok(fs.statSync(moved.resource.fsPath).isFile);

287 288 289 290 291 292 293 294 295 296 297
					assert.ok(createEvent);
					assert.ok(deleteEvent);
					assert.ok(moveEvent);

					assert.equal(moveEvent.resource.fsPath, resource.fsPath);
					assert.equal(moveEvent.target.resource.fsPath, moved.resource.fsPath);

					assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);

					toDispose.dispose();

E
Erich Gamma 已提交
298 299 300
					done();
				});
			});
B
Benjamin Pasero 已提交
301
		}, error => onError(error, done));
E
Erich Gamma 已提交
302 303
	});

B
Benjamin Pasero 已提交
304
	test('copyFile', function (done: () => void) {
305 306 307 308 309
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

E
Erich Gamma 已提交
310
		service.resolveFile(uri.file(path.join(testDir, 'index.html'))).done(source => {
311 312 313
			const resource = uri.file(path.join(testDir, 'other.html'));
			return service.copyFile(source.resource, resource).then(copied => {
				assert.equal(fs.existsSync(copied.resource.fsPath), true);
E
Erich Gamma 已提交
314 315
				assert.equal(fs.existsSync(source.resource.fsPath), true);

316 317 318 319 320 321
				assert.ok(event);
				assert.equal(event.resource.fsPath, source.resource.fsPath);
				assert.equal(event.operation, FileOperation.COPY);
				assert.equal(event.target.resource.fsPath, copied.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
322 323
				done();
			});
B
Benjamin Pasero 已提交
324
		}, error => onError(error, done));
E
Erich Gamma 已提交
325 326
	});

B
Benjamin Pasero 已提交
327
	test('copyFile - overwrite folder with file', function (done: () => void) {
328 329 330 331 332 333 334 335 336 337 338 339 340
		let createEvent: FileOperationEvent;
		let copyEvent: FileOperationEvent;
		let deleteEvent: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			if (e.operation === FileOperation.CREATE) {
				createEvent = e;
			} else if (e.operation === FileOperation.DELETE) {
				deleteEvent = e;
			} else if (e.operation === FileOperation.COPY) {
				copyEvent = e;
			}
		});

E
Erich Gamma 已提交
341
		service.resolveFile(uri.file(testDir)).done(parent => {
342 343 344 345
			const folderResource = uri.file(path.join(parent.resource.fsPath, 'conway.js'));
			return service.createFolder(folderResource).then(f => {
				const resource = uri.file(path.join(testDir, 'deep', 'conway.js'));
				return service.copyFile(resource, f.resource, true).then(copied => {
E
Erich Gamma 已提交
346 347 348
					assert.equal(fs.existsSync(copied.resource.fsPath), true);
					assert.ok(fs.statSync(copied.resource.fsPath).isFile);

349 350 351 352 353 354 355 356 357 358 359
					assert.ok(createEvent);
					assert.ok(deleteEvent);
					assert.ok(copyEvent);

					assert.equal(copyEvent.resource.fsPath, resource.fsPath);
					assert.equal(copyEvent.target.resource.fsPath, copied.resource.fsPath);

					assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);

					toDispose.dispose();

E
Erich Gamma 已提交
360 361 362
					done();
				});
			});
B
Benjamin Pasero 已提交
363
		}, error => onError(error, done));
E
Erich Gamma 已提交
364 365
	});

B
Benjamin Pasero 已提交
366
	test('importFile', function (done: () => void) {
367 368 369 370 371
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

E
Erich Gamma 已提交
372
		service.resolveFile(uri.file(path.join(testDir, 'deep'))).done(target => {
373 374
			const resource = uri.file(require.toUrl('./fixtures/service/index.html'));
			return service.importFile(resource, target.resource).then(res => {
E
Erich Gamma 已提交
375 376 377
				assert.equal(res.isNew, true);
				assert.equal(fs.existsSync(res.stat.resource.fsPath), true);

378 379 380 381 382 383
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.IMPORT);
				assert.equal(event.target.resource.fsPath, res.stat.resource.fsPath);
				toDispose.dispose();

E
Erich Gamma 已提交
384 385
				done();
			});
B
Benjamin Pasero 已提交
386
		}, error => onError(error, done));
E
Erich Gamma 已提交
387 388
	});

B
Benjamin Pasero 已提交
389
	test('importFile - MIX CASE', function (done: () => void) {
E
Erich Gamma 已提交
390 391 392 393 394 395 396 397 398 399 400 401 402 403
		service.resolveFile(uri.file(path.join(testDir, 'index.html'))).done(source => {
			return service.rename(source.resource, 'CONWAY.js').then(renamed => { // index.html => CONWAY.js
				assert.equal(fs.existsSync(renamed.resource.fsPath), true);
				assert.ok(fs.readdirSync(testDir).some(f => f === 'CONWAY.js'));

				return service.resolveFile(uri.file(path.join(testDir, 'deep', 'conway.js'))).done(source => {
					return service.importFile(source.resource, uri.file(testDir)).then(res => { // CONWAY.js => conway.js
						assert.equal(fs.existsSync(res.stat.resource.fsPath), true);
						assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js'));

						done();
					});
				});
			});
B
Benjamin Pasero 已提交
404
		}, error => onError(error, done));
E
Erich Gamma 已提交
405 406
	});

B
Benjamin Pasero 已提交
407
	test('importFile - overwrite folder with file', function (done: () => void) {
408 409 410 411 412 413 414 415 416 417 418 419 420
		let createEvent: FileOperationEvent;
		let importEvent: FileOperationEvent;
		let deleteEvent: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			if (e.operation === FileOperation.CREATE) {
				createEvent = e;
			} else if (e.operation === FileOperation.DELETE) {
				deleteEvent = e;
			} else if (e.operation === FileOperation.IMPORT) {
				importEvent = e;
			}
		});

E
Erich Gamma 已提交
421
		service.resolveFile(uri.file(testDir)).done(parent => {
422 423 424 425
			const folderResource = uri.file(path.join(parent.resource.fsPath, 'conway.js'));
			return service.createFolder(folderResource).then(f => {
				const resource = uri.file(path.join(testDir, 'deep', 'conway.js'));
				return service.importFile(resource, uri.file(testDir)).then(res => {
E
Erich Gamma 已提交
426 427 428 429
					assert.equal(fs.existsSync(res.stat.resource.fsPath), true);
					assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js'));
					assert.ok(fs.statSync(res.stat.resource.fsPath).isFile);

430 431 432 433 434 435 436 437 438 439 440
					assert.ok(createEvent);
					assert.ok(deleteEvent);
					assert.ok(importEvent);

					assert.equal(importEvent.resource.fsPath, resource.fsPath);
					assert.equal(importEvent.target.resource.fsPath, res.stat.resource.fsPath);

					assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);

					toDispose.dispose();

E
Erich Gamma 已提交
441 442 443
					done();
				});
			});
B
Benjamin Pasero 已提交
444
		}, error => onError(error, done));
E
Erich Gamma 已提交
445 446
	});

B
Benjamin Pasero 已提交
447
	test('importFile - same file', function (done: () => void) {
448 449 450 451 452 453
		service.resolveFile(uri.file(path.join(testDir, 'index.html'))).done(source => {
			return service.importFile(source.resource, uri.file(path.dirname(source.resource.fsPath))).then(imported => {
				assert.equal(imported.stat.size, source.size);

				done();
			});
B
Benjamin Pasero 已提交
454
		}, error => onError(error, done));
455 456
	});

B
Benjamin Pasero 已提交
457
	test('deleteFile', function (done: () => void) {
458 459 460 461 462 463 464
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'deep', 'conway.js'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
465 466 467
			return service.del(source.resource).then(() => {
				assert.equal(fs.existsSync(source.resource.fsPath), false);

468 469 470 471 472
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.DELETE);
				toDispose.dispose();

E
Erich Gamma 已提交
473 474
				done();
			});
B
Benjamin Pasero 已提交
475
		}, error => onError(error, done));
E
Erich Gamma 已提交
476 477
	});

B
Benjamin Pasero 已提交
478
	test('deleteFolder', function (done: () => void) {
479 480 481 482 483 484 485
		let event: FileOperationEvent;
		const toDispose = service.onAfterOperation(e => {
			event = e;
		});

		const resource = uri.file(path.join(testDir, 'deep'));
		service.resolveFile(resource).done(source => {
E
Erich Gamma 已提交
486 487 488
			return service.del(source.resource).then(() => {
				assert.equal(fs.existsSync(source.resource.fsPath), false);

489 490 491 492 493
				assert.ok(event);
				assert.equal(event.resource.fsPath, resource.fsPath);
				assert.equal(event.operation, FileOperation.DELETE);
				toDispose.dispose();

E
Erich Gamma 已提交
494 495
				done();
			});
B
Benjamin Pasero 已提交
496
		}, error => onError(error, done));
E
Erich Gamma 已提交
497 498
	});

B
Benjamin Pasero 已提交
499
	test('resolveFile', function (done: () => void) {
500
		service.resolveFile(uri.file(testDir), { resolveTo: [uri.file(path.join(testDir, 'deep'))] }).done(r => {
501
			assert.equal(r.children.length, 6);
E
Erich Gamma 已提交
502 503 504 505 506

			let deep = utils.getByName(r, 'deep');
			assert.equal(deep.children.length, 4);

			done();
B
Benjamin Pasero 已提交
507
		}, error => onError(error, done));
E
Erich Gamma 已提交
508 509
	});

B
Benjamin Pasero 已提交
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
	test('resolveFiles', function (done: () => void) {
		service.resolveFiles([
			{ resource: uri.file(testDir), options: { resolveTo: [uri.file(path.join(testDir, 'deep'))] } },
			{ resource: uri.file(path.join(testDir, 'deep')) }
		]).then(res => {
			const r1 = res[0];

			assert.equal(r1.children.length, 6);

			let deep = utils.getByName(r1, 'deep');
			assert.equal(deep.children.length, 4);

			const r2 = res[1];
			assert.equal(r2.children.length, 4);
			assert.equal(r2.name, 'deep');

			done();
		}, error => onError(error, done));
	});

530 531 532 533 534 535 536 537 538
	test('existsFile', function (done: () => void) {
		service.existsFile(uri.file(testDir)).then((exists) => {
			assert.equal(exists, true);

			service.existsFile(uri.file(testDir + 'something')).then((exists) => {
				assert.equal(exists, false);

				done();
			});
B
Benjamin Pasero 已提交
539
		}, error => onError(error, done));
540 541
	});

B
Benjamin Pasero 已提交
542
	test('updateContent', function (done: () => void) {
E
Erich Gamma 已提交
543 544 545 546 547 548 549 550 551 552 553 554
		let resource = uri.file(path.join(testDir, 'small.txt'));

		service.resolveContent(resource).done(c => {
			assert.equal(c.value, 'Small File');

			c.value = 'Updates to the small file';

			return service.updateContent(c.resource, c.value).then(c => {
				assert.equal(fs.readFileSync(resource.fsPath), 'Updates to the small file');

				done();
			});
B
Benjamin Pasero 已提交
555
		}, error => onError(error, done));
E
Erich Gamma 已提交
556 557
	});

B
Benjamin Pasero 已提交
558
	test('updateContent - use encoding (UTF 16 BE)', function (done: () => void) {
E
Erich Gamma 已提交
559
		let resource = uri.file(path.join(testDir, 'small.txt'));
B
Benjamin Pasero 已提交
560
		let encoding = 'utf16be';
E
Erich Gamma 已提交
561 562

		service.resolveContent(resource).done(c => {
B
Benjamin Pasero 已提交
563
			c.encoding = encoding;
E
Erich Gamma 已提交
564

B
Benjamin Pasero 已提交
565
			return service.updateContent(c.resource, c.value, { encoding: encoding }).then(c => {
K
katainaka0503 已提交
566
				return encodingLib.detectEncodingByBOM(c.resource.fsPath).then((enc) => {
B
Benjamin Pasero 已提交
567
					assert.equal(enc, encodingLib.UTF16be);
E
Erich Gamma 已提交
568

569
					return service.resolveContent(resource).then(c => {
B
Benjamin Pasero 已提交
570
						assert.equal(c.encoding, encoding);
571 572 573

						done();
					});
E
Erich Gamma 已提交
574 575
				});
			});
B
Benjamin Pasero 已提交
576
		}, error => onError(error, done));
E
Erich Gamma 已提交
577 578
	});

B
Benjamin Pasero 已提交
579
	test('updateContent - encoding preserved (UTF 16 LE)', function (done: () => void) {
B
Benjamin Pasero 已提交
580
		let encoding = 'utf16le';
E
Erich Gamma 已提交
581 582 583
		let resource = uri.file(path.join(testDir, 'some_utf16le.css'));

		service.resolveContent(resource).done(c => {
B
Benjamin Pasero 已提交
584
			assert.equal(c.encoding, encoding);
E
Erich Gamma 已提交
585 586 587

			c.value = 'Some updates';

B
Benjamin Pasero 已提交
588
			return service.updateContent(c.resource, c.value, { encoding: encoding }).then(c => {
K
katainaka0503 已提交
589
				return encodingLib.detectEncodingByBOM(c.resource.fsPath).then((enc) => {
B
Benjamin Pasero 已提交
590
					assert.equal(enc, encodingLib.UTF16le);
E
Erich Gamma 已提交
591

592
					return service.resolveContent(resource).then(c => {
B
Benjamin Pasero 已提交
593
						assert.equal(c.encoding, encoding);
594 595 596

						done();
					});
E
Erich Gamma 已提交
597 598
				});
			});
B
Benjamin Pasero 已提交
599
		}, error => onError(error, done));
E
Erich Gamma 已提交
600 601
	});

B
Benjamin Pasero 已提交
602
	test('resolveContent - FILE_IS_BINARY', function (done: () => void) {
E
Erich Gamma 已提交
603 604
		let resource = uri.file(path.join(testDir, 'binary.txt'));

605
		service.resolveContent(resource, { acceptTextOnly: true }).done(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
606 607 608 609 610 611 612
			assert.equal(e.fileOperationResult, FileOperationResult.FILE_IS_BINARY);

			return service.resolveContent(uri.file(path.join(testDir, 'small.txt')), { acceptTextOnly: true }).then(r => {
				assert.equal(r.name, 'small.txt');

				done();
			});
B
Benjamin Pasero 已提交
613
		}, error => onError(error, done));
E
Erich Gamma 已提交
614 615
	});

B
Benjamin Pasero 已提交
616
	test('resolveContent - FILE_IS_DIRECTORY', function (done: () => void) {
E
Erich Gamma 已提交
617 618
		let resource = uri.file(path.join(testDir, 'deep'));

619
		service.resolveContent(resource).done(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
620 621 622
			assert.equal(e.fileOperationResult, FileOperationResult.FILE_IS_DIRECTORY);

			done();
B
Benjamin Pasero 已提交
623
		}, error => onError(error, done));
E
Erich Gamma 已提交
624 625
	});

B
Benjamin Pasero 已提交
626
	test('resolveContent - FILE_NOT_FOUND', function (done: () => void) {
E
Erich Gamma 已提交
627 628
		let resource = uri.file(path.join(testDir, '404.html'));

629
		service.resolveContent(resource).done(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
630 631 632
			assert.equal(e.fileOperationResult, FileOperationResult.FILE_NOT_FOUND);

			done();
B
Benjamin Pasero 已提交
633
		}, error => onError(error, done));
E
Erich Gamma 已提交
634 635
	});

B
Benjamin Pasero 已提交
636
	test('resolveContent - FILE_NOT_MODIFIED_SINCE', function (done: () => void) {
E
Erich Gamma 已提交
637 638 639
		let resource = uri.file(path.join(testDir, 'index.html'));

		service.resolveContent(resource).done(c => {
640
			return service.resolveContent(resource, { etag: c.etag }).then(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
641 642 643 644
				assert.equal(e.fileOperationResult, FileOperationResult.FILE_NOT_MODIFIED_SINCE);

				done();
			});
B
Benjamin Pasero 已提交
645
		}, error => onError(error, done));
E
Erich Gamma 已提交
646 647
	});

B
Benjamin Pasero 已提交
648
	test('resolveContent - FILE_MODIFIED_SINCE', function (done: () => void) {
E
Erich Gamma 已提交
649 650 651 652 653
		let resource = uri.file(path.join(testDir, 'index.html'));

		service.resolveContent(resource).done(c => {
			fs.writeFileSync(resource.fsPath, 'Updates Incoming!');

654
			return service.updateContent(resource, c.value, { etag: c.etag, mtime: c.mtime - 1000 }).then(null, (e: IFileOperationResult) => {
E
Erich Gamma 已提交
655 656 657 658
				assert.equal(e.fileOperationResult, FileOperationResult.FILE_MODIFIED_SINCE);

				done();
			});
B
Benjamin Pasero 已提交
659
		}, error => onError(error, done));
E
Erich Gamma 已提交
660 661
	});

B
Benjamin Pasero 已提交
662
	test('resolveContent - encoding picked up', function (done: () => void) {
E
Erich Gamma 已提交
663
		let resource = uri.file(path.join(testDir, 'index.html'));
B
Benjamin Pasero 已提交
664
		let encoding = 'windows1252';
E
Erich Gamma 已提交
665

B
Benjamin Pasero 已提交
666 667
		service.resolveContent(resource, { encoding: encoding }).done(c => {
			assert.equal(c.encoding, encoding);
E
Erich Gamma 已提交
668 669

			done();
B
Benjamin Pasero 已提交
670
		}, error => onError(error, done));
E
Erich Gamma 已提交
671 672
	});

B
Benjamin Pasero 已提交
673
	test('resolveContent - user overrides BOM', function (done: () => void) {
E
Erich Gamma 已提交
674 675 676
		let resource = uri.file(path.join(testDir, 'some_utf16le.css'));

		service.resolveContent(resource, { encoding: 'windows1252' }).done(c => {
B
Benjamin Pasero 已提交
677
			assert.equal(c.encoding, 'windows1252');
E
Erich Gamma 已提交
678 679

			done();
B
Benjamin Pasero 已提交
680
		}, error => onError(error, done));
E
Erich Gamma 已提交
681 682
	});

B
Benjamin Pasero 已提交
683
	test('resolveContent - BOM removed', function (done: () => void) {
684 685 686
		let resource = uri.file(path.join(testDir, 'some_utf8_bom.txt'));

		service.resolveContent(resource).done(c => {
B
Benjamin Pasero 已提交
687
			assert.equal(encodingLib.detectEncodingByBOMFromBuffer(new Buffer(c.value), 512), null);
688 689

			done();
B
Benjamin Pasero 已提交
690
		}, error => onError(error, done));
691 692
	});

B
Benjamin Pasero 已提交
693
	test('resolveContent - invalid encoding', function (done: () => void) {
E
Erich Gamma 已提交
694 695 696
		let resource = uri.file(path.join(testDir, 'index.html'));

		service.resolveContent(resource, { encoding: 'superduper' }).done(c => {
B
Benjamin Pasero 已提交
697
			assert.equal(c.encoding, 'utf8');
E
Erich Gamma 已提交
698 699

			done();
B
Benjamin Pasero 已提交
700
		}, error => onError(error, done));
E
Erich Gamma 已提交
701 702
	});

B
Benjamin Pasero 已提交
703
	test('watchFileChanges', function (done: () => void) {
E
Erich Gamma 已提交
704 705 706 707
		let toWatch = uri.file(path.join(testDir, 'index.html'));

		service.watchFileChanges(toWatch);

708
		service.onFileChanges((e: FileChangesEvent) => {
E
Erich Gamma 已提交
709 710 711 712 713 714 715 716 717 718 719
			assert.ok(e);

			service.unwatchFileChanges(toWatch);
			done();
		});

		setTimeout(() => {
			fs.writeFileSync(toWatch.fsPath, 'Changes');
		}, 100);
	});

720 721 722 723 724
	test('watchFileChanges - support atomic save', function (done: () => void) {
		let toWatch = uri.file(path.join(testDir, 'index.html'));

		service.watchFileChanges(toWatch);

725
		service.onFileChanges((e: FileChangesEvent) => {
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
			assert.ok(e);

			service.unwatchFileChanges(toWatch);
			done();
		});

		setTimeout(() => {
			// Simulate atomic save by deleting the file, creating it under different name
			// and then replacing the previously deleted file with those contents
			const renamed = `${toWatch.fsPath}.bak`;
			fs.unlinkSync(toWatch.fsPath);
			fs.writeFileSync(renamed, 'Changes');
			fs.renameSync(renamed, toWatch.fsPath);
		}, 100);
	});

B
Benjamin Pasero 已提交
742
	test('options - encoding', function (done: () => void) {
E
Erich Gamma 已提交
743 744 745 746 747 748 749 750 751 752 753

		// setup
		let _id = uuid.generateUuid();
		let _testDir = path.join(parentDir, _id);
		let _sourceDir = require.toUrl('./fixtures/service');

		extfs.copy(_sourceDir, _testDir, () => {
			let encodingOverride: IEncodingOverride[] = [];
			encodingOverride.push({
				resource: uri.file(path.join(testDir, 'deep')),
				encoding: 'utf16le'
B
Benjamin Pasero 已提交
754
			});
E
Erich Gamma 已提交
755

B
Benjamin Pasero 已提交
756
			let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), {
E
Erich Gamma 已提交
757
				encoding: 'windows1252',
B
Benjamin Pasero 已提交
758
				encodingOverride,
E
Erich Gamma 已提交
759
				disableWatcher: true
B
Benjamin Pasero 已提交
760
			});
E
Erich Gamma 已提交
761 762

			_service.resolveContent(uri.file(path.join(testDir, 'index.html'))).done(c => {
B
Benjamin Pasero 已提交
763
				assert.equal(c.encoding, 'windows1252');
E
Erich Gamma 已提交
764 765

				return _service.resolveContent(uri.file(path.join(testDir, 'deep', 'conway.js'))).done(c => {
B
Benjamin Pasero 已提交
766
					assert.equal(c.encoding, 'utf16le');
E
Erich Gamma 已提交
767 768 769 770 771 772 773 774

					// teardown
					_service.dispose();
					done();
				});
			});
		});
	});
775

B
Benjamin Pasero 已提交
776
	test('UTF 8 BOMs', function (done: () => void) {
777 778 779 780 781 782 783

		// setup
		let _id = uuid.generateUuid();
		let _testDir = path.join(parentDir, _id);
		let _sourceDir = require.toUrl('./fixtures/service');
		let resource = uri.file(path.join(testDir, 'index.html'));

B
Benjamin Pasero 已提交
784
		let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), {
B
wip  
Benjamin Pasero 已提交
785
			disableWatcher: true
B
Benjamin Pasero 已提交
786
		});
787

B
wip  
Benjamin Pasero 已提交
788
		extfs.copy(_sourceDir, _testDir, () => {
789
			fs.readFile(resource.fsPath, (error, data) => {
B
Benjamin Pasero 已提交
790
				assert.equal(encodingLib.detectEncodingByBOMFromBuffer(data, 512), null);
791

B
wip  
Benjamin Pasero 已提交
792
				// Update content: UTF_8 => UTF_8_BOM
B
Benjamin Pasero 已提交
793
				_service.updateContent(resource, 'Hello Bom', { encoding: encodingLib.UTF8_with_bom }).done(() => {
794
					fs.readFile(resource.fsPath, (error, data) => {
B
Benjamin Pasero 已提交
795
						assert.equal(encodingLib.detectEncodingByBOMFromBuffer(data, 512), encodingLib.UTF8);
796

B
wip  
Benjamin Pasero 已提交
797
						// Update content: PRESERVE BOM when using UTF-8
B
Benjamin Pasero 已提交
798
						_service.updateContent(resource, 'Please stay Bom', { encoding: encodingLib.UTF8 }).done(() => {
799
							fs.readFile(resource.fsPath, (error, data) => {
B
Benjamin Pasero 已提交
800
								assert.equal(encodingLib.detectEncodingByBOMFromBuffer(data, 512), encodingLib.UTF8);
801

B
wip  
Benjamin Pasero 已提交
802
								// Update content: REMOVE BOM
B
Benjamin Pasero 已提交
803
								_service.updateContent(resource, 'Go away Bom', { encoding: encodingLib.UTF8, overwriteEncoding: true }).done(() => {
804
									fs.readFile(resource.fsPath, (error, data) => {
B
Benjamin Pasero 已提交
805
										assert.equal(encodingLib.detectEncodingByBOMFromBuffer(data, 512), null);
806

B
wip  
Benjamin Pasero 已提交
807
										// Update content: BOM comes not back
B
Benjamin Pasero 已提交
808
										_service.updateContent(resource, 'Do not come back Bom', { encoding: encodingLib.UTF8 }).done(() => {
809
											fs.readFile(resource.fsPath, (error, data) => {
B
Benjamin Pasero 已提交
810
												assert.equal(encodingLib.detectEncodingByBOMFromBuffer(data, 512), null);
811 812 813 814 815 816 817 818 819 820 821 822 823 824

												_service.dispose();
												done();
											});
										});
									});
								});
							});
						});
					});
				});
			});
		});
	});
825
});