mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
226 lines
8.3 KiB
TypeScript
226 lines
8.3 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* 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 assert = require('assert');
|
|
|
|
import platform = require('vs/base/common/platform');
|
|
import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
|
|
import uri from 'vs/base/common/uri';
|
|
import { IRawFileChange, toFileChangesEvent, normalize } from 'vs/workbench/services/files/node/watcher/common';
|
|
import Event, { Emitter } from 'vs/base/common/event';
|
|
|
|
class TestFileWatcher {
|
|
private _onFileChanges: Emitter<FileChangesEvent>;
|
|
|
|
constructor() {
|
|
this._onFileChanges = new Emitter<FileChangesEvent>();
|
|
}
|
|
|
|
public get onFileChanges(): Event<FileChangesEvent> {
|
|
return this._onFileChanges.event;
|
|
}
|
|
|
|
public report(changes: IRawFileChange[]): void {
|
|
this.onRawFileEvents(changes);
|
|
}
|
|
|
|
private onRawFileEvents(events: IRawFileChange[]): void {
|
|
|
|
// Normalize
|
|
let normalizedEvents = normalize(events);
|
|
|
|
// Emit through broadcast service
|
|
if (normalizedEvents.length > 0) {
|
|
this._onFileChanges.fire(toFileChangesEvent(normalizedEvents));
|
|
}
|
|
}
|
|
}
|
|
|
|
enum Path {
|
|
UNIX,
|
|
WINDOWS,
|
|
UNC
|
|
};
|
|
|
|
suite('Watcher', () => {
|
|
|
|
test('watching - simple add/update/delete', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const added = uri.file('/users/data/src/added.txt');
|
|
const updated = uri.file('/users/data/src/updated.txt');
|
|
const deleted = uri.file('/users/data/src/deleted.txt');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: added.fsPath, type: FileChangeType.ADDED },
|
|
{ path: updated.fsPath, type: FileChangeType.UPDATED },
|
|
{ path: deleted.fsPath, type: FileChangeType.DELETED },
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 3);
|
|
assert.ok(e.contains(added, FileChangeType.ADDED));
|
|
assert.ok(e.contains(updated, FileChangeType.UPDATED));
|
|
assert.ok(e.contains(deleted, FileChangeType.DELETED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
|
|
let pathSpecs = platform.isWindows ? [Path.WINDOWS, Path.UNC] : [Path.UNIX];
|
|
pathSpecs.forEach((p) => {
|
|
test('watching - delete only reported for top level folder (' + p + ')', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const deletedFolderA = uri.file(p === Path.UNIX ? '/users/data/src/todelete1' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\todelete1' : '\\\\localhost\\users\\data\\src\\todelete1');
|
|
const deletedFolderB = uri.file(p === Path.UNIX ? '/users/data/src/todelete2' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\todelete2' : '\\\\localhost\\users\\data\\src\\todelete2');
|
|
const deletedFolderBF1 = uri.file(p === Path.UNIX ? '/users/data/src/todelete2/file.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\todelete2\\file.txt' : '\\\\localhost\\users\\data\\src\\todelete2\\file.txt');
|
|
const deletedFolderBF2 = uri.file(p === Path.UNIX ? '/users/data/src/todelete2/more/test.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\todelete2\\more\\test.txt' : '\\\\localhost\\users\\data\\src\\todelete2\\more\\test.txt');
|
|
const deletedFolderBF3 = uri.file(p === Path.UNIX ? '/users/data/src/todelete2/super/bar/foo.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\todelete2\\super\\bar\\foo.txt' : '\\\\localhost\\users\\data\\src\\todelete2\\super\\bar\\foo.txt');
|
|
const deletedFileA = uri.file(p === Path.UNIX ? '/users/data/src/deleteme.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\deleteme.txt' : '\\\\localhost\\users\\data\\src\\deleteme.txt');
|
|
|
|
const addedFile = uri.file(p === Path.UNIX ? '/users/data/src/added.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\added.txt' : '\\\\localhost\\users\\data\\src\\added.txt');
|
|
const updatedFile = uri.file(p === Path.UNIX ? '/users/data/src/updated.txt' : p === Path.WINDOWS ? 'C:\\users\\data\\src\\updated.txt' : '\\\\localhost\\users\\data\\src\\updated.txt');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: deletedFolderA.fsPath, type: FileChangeType.DELETED },
|
|
{ path: deletedFolderB.fsPath, type: FileChangeType.DELETED },
|
|
{ path: deletedFolderBF1.fsPath, type: FileChangeType.DELETED },
|
|
{ path: deletedFolderBF2.fsPath, type: FileChangeType.DELETED },
|
|
{ path: deletedFolderBF3.fsPath, type: FileChangeType.DELETED },
|
|
{ path: deletedFileA.fsPath, type: FileChangeType.DELETED },
|
|
{ path: addedFile.fsPath, type: FileChangeType.ADDED },
|
|
{ path: updatedFile.fsPath, type: FileChangeType.UPDATED }
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 5);
|
|
|
|
assert.ok(e.contains(deletedFolderA, FileChangeType.DELETED));
|
|
assert.ok(e.contains(deletedFolderB, FileChangeType.DELETED));
|
|
assert.ok(e.contains(deletedFileA, FileChangeType.DELETED));
|
|
assert.ok(e.contains(addedFile, FileChangeType.ADDED));
|
|
assert.ok(e.contains(updatedFile, FileChangeType.UPDATED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
});
|
|
|
|
test('watching - event normalization: ignore CREATE followed by DELETE', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const created = uri.file('/users/data/src/related');
|
|
const deleted = uri.file('/users/data/src/related');
|
|
const unrelated = uri.file('/users/data/src/unrelated');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: created.fsPath, type: FileChangeType.ADDED },
|
|
{ path: deleted.fsPath, type: FileChangeType.DELETED },
|
|
{ path: unrelated.fsPath, type: FileChangeType.UPDATED },
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 1);
|
|
|
|
assert.ok(e.contains(unrelated, FileChangeType.UPDATED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
|
|
test('watching - event normalization: flatten DELETE followed by CREATE into CHANGE', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const deleted = uri.file('/users/data/src/related');
|
|
const created = uri.file('/users/data/src/related');
|
|
const unrelated = uri.file('/users/data/src/unrelated');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: deleted.fsPath, type: FileChangeType.DELETED },
|
|
{ path: created.fsPath, type: FileChangeType.ADDED },
|
|
{ path: unrelated.fsPath, type: FileChangeType.UPDATED },
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 2);
|
|
|
|
assert.ok(e.contains(deleted, FileChangeType.UPDATED));
|
|
assert.ok(e.contains(unrelated, FileChangeType.UPDATED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
|
|
test('watching - event normalization: ignore UPDATE when CREATE received', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const created = uri.file('/users/data/src/related');
|
|
const updated = uri.file('/users/data/src/related');
|
|
const unrelated = uri.file('/users/data/src/unrelated');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: created.fsPath, type: FileChangeType.ADDED },
|
|
{ path: updated.fsPath, type: FileChangeType.UPDATED },
|
|
{ path: unrelated.fsPath, type: FileChangeType.UPDATED },
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 2);
|
|
|
|
assert.ok(e.contains(created, FileChangeType.ADDED));
|
|
assert.ok(!e.contains(created, FileChangeType.UPDATED));
|
|
assert.ok(e.contains(unrelated, FileChangeType.UPDATED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
|
|
test('watching - event normalization: apply DELETE', function (done: () => void) {
|
|
const watch = new TestFileWatcher();
|
|
|
|
const updated = uri.file('/users/data/src/related');
|
|
const updated2 = uri.file('/users/data/src/related');
|
|
const deleted = uri.file('/users/data/src/related');
|
|
const unrelated = uri.file('/users/data/src/unrelated');
|
|
|
|
const raw: IRawFileChange[] = [
|
|
{ path: updated.fsPath, type: FileChangeType.UPDATED },
|
|
{ path: updated2.fsPath, type: FileChangeType.UPDATED },
|
|
{ path: unrelated.fsPath, type: FileChangeType.UPDATED },
|
|
{ path: updated.fsPath, type: FileChangeType.DELETED }
|
|
];
|
|
|
|
watch.onFileChanges(e => {
|
|
assert.ok(e);
|
|
assert.equal(e.changes.length, 2);
|
|
|
|
assert.ok(e.contains(deleted, FileChangeType.DELETED));
|
|
assert.ok(!e.contains(updated, FileChangeType.UPDATED));
|
|
assert.ok(e.contains(unrelated, FileChangeType.UPDATED));
|
|
|
|
done();
|
|
});
|
|
|
|
watch.report(raw);
|
|
});
|
|
}); |