mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 01:25:36 -05:00
Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880)
This commit is contained in:
@@ -1,615 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import { Readable } from 'stream';
|
||||
import { canNormalize } from 'vs/base/common/normalization';
|
||||
import { isLinux, isWindows } from 'vs/base/common/platform';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
|
||||
const ignore = () => { };
|
||||
|
||||
const mkdirp = (path: string, mode: number, callback: (error: any) => void) => {
|
||||
extfs.mkdirp(path, mode).then(() => callback(null), error => callback(error));
|
||||
};
|
||||
|
||||
const chunkSize = 64 * 1024;
|
||||
const readError = 'Error while reading';
|
||||
function toReadable(value: string, throwError?: boolean): Readable {
|
||||
const totalChunks = Math.ceil(value.length / chunkSize);
|
||||
const stringChunks: string[] = [];
|
||||
|
||||
for (let i = 0, j = 0; i < totalChunks; ++i, j += chunkSize) {
|
||||
stringChunks[i] = value.substr(j, chunkSize);
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
return new Readable({
|
||||
read: function () {
|
||||
if (throwError) {
|
||||
this.emit('error', new Error(readError));
|
||||
}
|
||||
|
||||
let res!: string;
|
||||
let canPush = true;
|
||||
while (canPush && (res = stringChunks[counter++])) {
|
||||
canPush = this.push(res);
|
||||
}
|
||||
|
||||
// EOS
|
||||
if (!res) {
|
||||
this.push(null);
|
||||
}
|
||||
},
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
|
||||
suite('Extfs', () => {
|
||||
|
||||
test('mkdirp', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
}); // 493 = 0755
|
||||
});
|
||||
|
||||
test('stat link', function (done) {
|
||||
if (isWindows) {
|
||||
// Symlinks are not the same on win, and we can not create them programitically without admin privileges
|
||||
return done();
|
||||
}
|
||||
|
||||
const id1 = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id1);
|
||||
const directory = path.join(parentDir, 'extfs', id1);
|
||||
|
||||
const id2 = uuid.generateUuid();
|
||||
const symbolicLink = path.join(parentDir, 'extfs', id2);
|
||||
|
||||
mkdirp(directory, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
fs.symlinkSync(directory, symbolicLink);
|
||||
|
||||
extfs.statLink(directory, (error, statAndIsLink) => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(!statAndIsLink!.isSymbolicLink);
|
||||
|
||||
extfs.statLink(symbolicLink, (error, statAndIsLink) => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(statAndIsLink!.isSymbolicLink);
|
||||
extfs.delSync(directory);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('delSync - swallows file not found error', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
extfs.delSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('delSync - simple', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
extfs.delSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
done();
|
||||
}); // 493 = 0755
|
||||
});
|
||||
|
||||
test('delSync - recursive folder structure', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
|
||||
|
||||
extfs.delSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
done();
|
||||
}); // 493 = 0755
|
||||
});
|
||||
|
||||
test('copy, move and delete', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const id2 = uuid.generateUuid();
|
||||
const sourceDir = getPathFromAmdModule(require, './fixtures');
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', 'extfs');
|
||||
const targetDir = path.join(parentDir, id);
|
||||
const targetDir2 = path.join(parentDir, id2);
|
||||
|
||||
extfs.copy(sourceDir, targetDir, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(targetDir));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'site.css')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'examples')));
|
||||
assert.ok(fs.statSync(path.join(targetDir, 'examples')).isDirectory());
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'examples', 'small.jxs')));
|
||||
|
||||
extfs.mv(targetDir, targetDir2, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(!fs.existsSync(targetDir));
|
||||
assert.ok(fs.existsSync(targetDir2));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'site.css')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'examples')));
|
||||
assert.ok(fs.statSync(path.join(targetDir2, 'examples')).isDirectory());
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'examples', 'small.jxs')));
|
||||
|
||||
extfs.mv(path.join(targetDir2, 'index.html'), path.join(targetDir2, 'index_moved.html'), error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(!fs.existsSync(path.join(targetDir2, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'index_moved.html')));
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
}, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
assert.ok(!fs.existsSync(parentDir));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('readdir', function (done) {
|
||||
if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id, 'öäü');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.readdir(path.join(parentDir, 'extfs', id), (error, children) => {
|
||||
assert.equal(children.some(n => n === 'öäü'), true); // Mac always converts to NFD, so
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
}); // 493 = 0755
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (string)', function (done) {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
testWriteFileAndFlush(smallData, smallData, bigData, bigData, done);
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (Buffer)', function (done) {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
testWriteFileAndFlush(Buffer.from(smallData), smallData, Buffer.from(bigData), bigData, done);
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (UInt8Array)', function (done) {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
testWriteFileAndFlush(new TextEncoder().encode(smallData), smallData, new TextEncoder().encode(bigData), bigData, done);
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (stream)', function (done) {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
testWriteFileAndFlush(toReadable(smallData), smallData, toReadable(bigData), bigData, done);
|
||||
});
|
||||
|
||||
function testWriteFileAndFlush(
|
||||
smallData: string | Buffer | NodeJS.ReadableStream | Uint8Array,
|
||||
smallDataValue: string,
|
||||
bigData: string | Buffer | NodeJS.ReadableStream | Uint8Array,
|
||||
bigDataValue: string,
|
||||
done: (error: Error | null) => void
|
||||
): void {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.writeFileAndFlush(testFile, smallData, null!, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.equal(fs.readFileSync(testFile), smallDataValue);
|
||||
|
||||
extfs.writeFileAndFlush(testFile, bigData, null!, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.equal(fs.readFileSync(testFile), bigDataValue);
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test('writeFileAndFlush (file stream)', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const sourceFile = getPathFromAmdModule(require, './fixtures/index.html');
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null!, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.equal(fs.readFileSync(testFile).toString(), fs.readFileSync(sourceFile).toString());
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (string, error handling)', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
extfs.writeFileAndFlush(testFile, 'Hello World', null!, error => {
|
||||
if (!error) {
|
||||
return done(new Error('Expected error for writing to readonly file'));
|
||||
}
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (stream, error handling EISDIR)', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
const readable = toReadable('Hello World');
|
||||
extfs.writeFileAndFlush(testFile, readable, null!, error => {
|
||||
if (!error || (<any>error).code !== 'EISDIR') {
|
||||
return done(new Error('Expected EISDIR error for writing to folder but got: ' + (error ? (<any>error).code : 'no error')));
|
||||
}
|
||||
|
||||
// verify that the stream is still consumable (for https://github.com/Microsoft/vscode/issues/42542)
|
||||
assert.equal(readable.read(), 'Hello World');
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (stream, error handling READERROR)', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.writeFileAndFlush(testFile, toReadable('Hello World', true /* throw error */), null!, error => {
|
||||
if (!error || error.message !== readError) {
|
||||
return done(new Error('Expected error for writing to folder'));
|
||||
}
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (stream, error handling EACCES)', function (done) {
|
||||
if (isLinux) {
|
||||
return done(); // somehow this test fails on Linux in our TFS builds
|
||||
}
|
||||
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.writeFileSync(testFile, '');
|
||||
fs.chmodSync(testFile, 33060); // make readonly
|
||||
|
||||
extfs.writeFileAndFlush(testFile, toReadable('Hello World'), null!, error => {
|
||||
if (!error || !((<any>error).code !== 'EACCES' || (<any>error).code !== 'EPERM')) {
|
||||
return done(new Error('Expected EACCES/EPERM error for writing to folder but got: ' + (error ? (<any>error).code : 'no error')));
|
||||
}
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlush (file stream, error handling)', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const sourceFile = getPathFromAmdModule(require, './fixtures/index.html');
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
extfs.writeFileAndFlush(testFile, fs.createReadStream(sourceFile), null!, error => {
|
||||
if (!error) {
|
||||
return done(new Error('Expected error for writing to folder'));
|
||||
}
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFileAndFlushSync', function (done) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
if (error) {
|
||||
return done(error);
|
||||
}
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
extfs.writeFileAndFlushSync(testFile, 'Hello World', null!);
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World');
|
||||
|
||||
const largeString = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
extfs.writeFileAndFlushSync(testFile, largeString, null!);
|
||||
assert.equal(fs.readFileSync(testFile), largeString);
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
|
||||
test('realcase', (done) => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
|
||||
// {{SQL CARBON EDIT}} don't run this test case on Windows as this fails in VSO
|
||||
// assume case insensitive file system
|
||||
if (process.platform === 'darwin') {
|
||||
const upper = newDir.toUpperCase();
|
||||
const real = extfs.realcaseSync(upper);
|
||||
|
||||
if (real) { // can be null in case of permission errors
|
||||
assert.notEqual(real, upper);
|
||||
assert.equal(real.toUpperCase(), upper);
|
||||
assert.equal(real, newDir);
|
||||
}
|
||||
}
|
||||
|
||||
// linux, unix, etc. -> assume case sensitive file system
|
||||
else if (process.platform !== 'win32') {
|
||||
const real = extfs.realcaseSync(newDir);
|
||||
assert.equal(real, newDir);
|
||||
}
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
|
||||
test('realpath', (done) => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
|
||||
extfs.realpath(newDir, (error, realpath) => {
|
||||
assert.ok(realpath);
|
||||
assert.ok(!error);
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('realpathSync', (done) => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
mkdirp(newDir, 493, error => {
|
||||
let realpath!: string;
|
||||
try {
|
||||
realpath = extfs.realpathSync(newDir);
|
||||
} catch (error) {
|
||||
assert.ok(!error);
|
||||
}
|
||||
assert.ok(realpath!);
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
|
||||
test('mkdirp cancellation', (done) => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
const source = new CancellationTokenSource();
|
||||
|
||||
const mkdirpPromise = extfs.mkdirp(newDir, 493, source.token);
|
||||
source.cancel();
|
||||
|
||||
return mkdirpPromise.then(res => {
|
||||
assert.equal(res, false);
|
||||
|
||||
extfs.del(parentDir, os.tmpdir(), done, ignore);
|
||||
});
|
||||
});
|
||||
|
||||
test('sanitizeFilePath', () => {
|
||||
if (isWindows) {
|
||||
assert.equal(extfs.sanitizeFilePath('.', 'C:\\the\\cwd'), 'C:\\the\\cwd');
|
||||
assert.equal(extfs.sanitizeFilePath('', 'C:\\the\\cwd'), 'C:\\the\\cwd');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('C:', 'C:\\the\\cwd'), 'C:\\');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\', 'C:\\the\\cwd'), 'C:\\');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\\\', 'C:\\the\\cwd'), 'C:\\');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\folder\\my.txt', 'C:\\the\\cwd'), 'C:\\folder\\my.txt');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\folder\\my', 'C:\\the\\cwd'), 'C:\\folder\\my');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\folder\\..\\my', 'C:\\the\\cwd'), 'C:\\my');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\folder\\my\\', 'C:\\the\\cwd'), 'C:\\folder\\my');
|
||||
assert.equal(extfs.sanitizeFilePath('C:\\folder\\my\\\\\\', 'C:\\the\\cwd'), 'C:\\folder\\my');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('my.txt', 'C:\\the\\cwd'), 'C:\\the\\cwd\\my.txt');
|
||||
assert.equal(extfs.sanitizeFilePath('my.txt\\', 'C:\\the\\cwd'), 'C:\\the\\cwd\\my.txt');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('\\\\localhost\\folder\\my', 'C:\\the\\cwd'), '\\\\localhost\\folder\\my');
|
||||
assert.equal(extfs.sanitizeFilePath('\\\\localhost\\folder\\my\\', 'C:\\the\\cwd'), '\\\\localhost\\folder\\my');
|
||||
} else {
|
||||
assert.equal(extfs.sanitizeFilePath('.', '/the/cwd'), '/the/cwd');
|
||||
assert.equal(extfs.sanitizeFilePath('', '/the/cwd'), '/the/cwd');
|
||||
assert.equal(extfs.sanitizeFilePath('/', '/the/cwd'), '/');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('/folder/my.txt', '/the/cwd'), '/folder/my.txt');
|
||||
assert.equal(extfs.sanitizeFilePath('/folder/my', '/the/cwd'), '/folder/my');
|
||||
assert.equal(extfs.sanitizeFilePath('/folder/../my', '/the/cwd'), '/my');
|
||||
assert.equal(extfs.sanitizeFilePath('/folder/my/', '/the/cwd'), '/folder/my');
|
||||
assert.equal(extfs.sanitizeFilePath('/folder/my///', '/the/cwd'), '/folder/my');
|
||||
|
||||
assert.equal(extfs.sanitizeFilePath('my.txt', '/the/cwd'), '/the/cwd/my.txt');
|
||||
assert.equal(extfs.sanitizeFilePath('my.txt/', '/the/cwd'), '/the/cwd/my.txt');
|
||||
}
|
||||
});
|
||||
});
|
||||
73
src/vs/base/test/node/extpath.test.ts
Normal file
73
src/vs/base/test/node/extpath.test.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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';
|
||||
import * as os from 'os';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { realcaseSync, realpath, realpathSync } from 'vs/base/node/extpath';
|
||||
|
||||
suite('Extpath', () => {
|
||||
|
||||
test('realcase', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extpath', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
// assume case insensitive file system
|
||||
if (process.platform === 'win32' || process.platform === 'darwin') {
|
||||
const upper = newDir.toUpperCase();
|
||||
const real = realcaseSync(upper);
|
||||
|
||||
if (real) { // can be null in case of permission errors
|
||||
assert.notEqual(real, upper);
|
||||
assert.equal(real.toUpperCase(), upper);
|
||||
assert.equal(real, newDir);
|
||||
}
|
||||
}
|
||||
|
||||
// linux, unix, etc. -> assume case sensitive file system
|
||||
else {
|
||||
const real = realcaseSync(newDir);
|
||||
assert.equal(real, newDir);
|
||||
}
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('realpath', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extpath', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
const realpathVal = await realpath(newDir);
|
||||
assert.ok(realpathVal);
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('realpathSync', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extpath', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
let realpath!: string;
|
||||
try {
|
||||
realpath = realpathSync(newDir);
|
||||
} catch (error) {
|
||||
assert.ok(!error);
|
||||
}
|
||||
assert.ok(realpath!);
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
});
|
||||
@@ -1,488 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as flow from 'vs/base/node/flow';
|
||||
|
||||
const loop = flow.loop;
|
||||
const sequence = flow.sequence;
|
||||
const parallel = flow.parallel;
|
||||
|
||||
suite('Flow', () => {
|
||||
function assertCounterEquals(counter: number, expected: number): void {
|
||||
assert.ok(counter === expected, 'Expected ' + expected + ' assertions, but got ' + counter);
|
||||
}
|
||||
|
||||
function syncThrowsError(callback: any): void {
|
||||
callback(new Error('foo'), null);
|
||||
}
|
||||
|
||||
function syncSequenceGetThrowsError(value: any, callback: any) {
|
||||
sequence(
|
||||
function onError(error) {
|
||||
callback(error, null);
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
syncThrowsError(this);
|
||||
},
|
||||
|
||||
function handleFirst(first: number) {
|
||||
//Foo
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function syncGet(value: any, callback: any): void {
|
||||
callback(null, value);
|
||||
}
|
||||
|
||||
function syncGetError(value: any, callback: any): void {
|
||||
callback(new Error(''), null);
|
||||
}
|
||||
|
||||
function asyncGet(value: any, callback: any): void {
|
||||
process.nextTick(function () {
|
||||
callback(null, value);
|
||||
});
|
||||
}
|
||||
|
||||
function asyncGetError(value: any, callback: any): void {
|
||||
process.nextTick(function () {
|
||||
callback(new Error(''), null);
|
||||
});
|
||||
}
|
||||
|
||||
test('loopSync', function (done: () => void) {
|
||||
const elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback, index, total) {
|
||||
assert.ok(index === 0 || index === 1 || index === 2);
|
||||
assert.deepEqual(3, total);
|
||||
callback(null, element);
|
||||
}, function (error, result) {
|
||||
assert.equal(error, null);
|
||||
assert.deepEqual(result, elements);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopByFunctionSync', function (done: () => void) {
|
||||
const elements = function (callback: Function) {
|
||||
callback(null, ['1', '2', '3']);
|
||||
};
|
||||
|
||||
loop(elements, function (element, callback) {
|
||||
callback(null, element);
|
||||
}, function (error, result) {
|
||||
assert.equal(error, null);
|
||||
assert.deepEqual(result, ['1', '2', '3']);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopByFunctionAsync', function (done: () => void) {
|
||||
const elements = function (callback: Function) {
|
||||
process.nextTick(function () {
|
||||
callback(null, ['1', '2', '3']);
|
||||
});
|
||||
};
|
||||
|
||||
loop(elements, function (element, callback) {
|
||||
callback(null, element);
|
||||
}, function (error, result) {
|
||||
assert.equal(error, null);
|
||||
assert.deepEqual(result, ['1', '2', '3']);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopSyncErrorByThrow', function (done: () => void) {
|
||||
const elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback) {
|
||||
if (element === '2') {
|
||||
throw new Error('foo');
|
||||
} else {
|
||||
callback(null, element);
|
||||
}
|
||||
}, function (error, result) {
|
||||
assert.ok(error);
|
||||
assert.ok(!result);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopSyncErrorByCallback', function (done: () => void) {
|
||||
const elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback) {
|
||||
if (element === '2') {
|
||||
callback(new Error('foo'), null);
|
||||
} else {
|
||||
callback(null, element);
|
||||
}
|
||||
}, function (error, result) {
|
||||
assert.ok(error);
|
||||
assert.ok(!result);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopAsync', function (done: () => void) {
|
||||
const elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback) {
|
||||
process.nextTick(function () {
|
||||
callback(null, element);
|
||||
});
|
||||
}, function (error, result) {
|
||||
assert.equal(error, null);
|
||||
assert.deepEqual(result, elements);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loopAsyncErrorByCallback', function (done: () => void) {
|
||||
const elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback) {
|
||||
process.nextTick(function () {
|
||||
if (element === '2') {
|
||||
callback(new Error('foo'), null);
|
||||
} else {
|
||||
callback(null, element);
|
||||
}
|
||||
});
|
||||
}, function (error, result) {
|
||||
assert.ok(error);
|
||||
assert.ok(!result);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('sequenceSync', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
syncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
syncGet('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(this: any, second: any) {
|
||||
assert.deepEqual('2', second);
|
||||
assertionCount++;
|
||||
syncGet(null, this);
|
||||
},
|
||||
|
||||
function handleThird(third: any) {
|
||||
assert.ok(!third);
|
||||
assertionCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 3);
|
||||
assertCounterEquals(errorCount, 0);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('sequenceAsync', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
asyncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
asyncGet('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(this: any, second: number) {
|
||||
assert.deepEqual('2', second);
|
||||
assertionCount++;
|
||||
asyncGet(null, this);
|
||||
},
|
||||
|
||||
function handleThird(third: number) {
|
||||
assert.ok(!third);
|
||||
assertionCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 3);
|
||||
assertCounterEquals(errorCount, 0);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('sequenceSyncErrorByThrow', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 1);
|
||||
assertCounterEquals(errorCount, 1);
|
||||
done();
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
syncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
syncGet('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(second: number) {
|
||||
if (true) {
|
||||
throw new Error('');
|
||||
}
|
||||
// assertionCount++;
|
||||
// syncGet(null, this);
|
||||
},
|
||||
|
||||
function handleThird(third: number) {
|
||||
throw new Error('We should not be here');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('sequenceSyncErrorByCallback', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 1);
|
||||
assertCounterEquals(errorCount, 1);
|
||||
done();
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
syncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
syncGetError('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(second: number) {
|
||||
throw new Error('We should not be here');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('sequenceAsyncErrorByThrow', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 1);
|
||||
assertCounterEquals(errorCount, 1);
|
||||
done();
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
asyncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
asyncGet('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(second: number) {
|
||||
if (true) {
|
||||
throw new Error('');
|
||||
}
|
||||
// assertionCount++;
|
||||
// asyncGet(null, this);
|
||||
},
|
||||
|
||||
function handleThird(third: number) {
|
||||
throw new Error('We should not be here');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('sequenceAsyncErrorByCallback', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 1);
|
||||
assertCounterEquals(errorCount, 1);
|
||||
done();
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
asyncGet('1', this);
|
||||
},
|
||||
|
||||
function handleFirst(this: any, first: number) {
|
||||
assert.deepEqual('1', first);
|
||||
assertionCount++;
|
||||
asyncGetError('2', this);
|
||||
},
|
||||
|
||||
function handleSecond(second: number) {
|
||||
throw new Error('We should not be here');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('syncChainedSequenceError', function (done: () => void) {
|
||||
sequence(
|
||||
function onError(error) {
|
||||
done();
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
syncSequenceGetThrowsError('1', this);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('tolerateBooleanResults', function (done: () => void) {
|
||||
let assertionCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
sequence(
|
||||
function onError(error) {
|
||||
errorCount++;
|
||||
},
|
||||
|
||||
function getFirst(this: any) {
|
||||
this(true);
|
||||
},
|
||||
|
||||
function getSecond(this: any, result: boolean) {
|
||||
assert.equal(result, true);
|
||||
this(false);
|
||||
},
|
||||
|
||||
function last(result: boolean) {
|
||||
assert.equal(result, false);
|
||||
assertionCount++;
|
||||
|
||||
assertCounterEquals(assertionCount, 1);
|
||||
assertCounterEquals(errorCount, 0);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('loopTolerateBooleanResults', function (done: () => void) {
|
||||
let elements = ['1', '2', '3'];
|
||||
loop(elements, function (element, callback) {
|
||||
process.nextTick(function () {
|
||||
(<any>callback)(true);
|
||||
});
|
||||
}, function (error, result) {
|
||||
assert.equal(error, null);
|
||||
assert.deepEqual(result, [true, true, true]);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('parallel', function (done: () => void) {
|
||||
let elements = [1, 2, 3, 4, 5];
|
||||
let sum = 0;
|
||||
|
||||
parallel(elements, function (element, callback) {
|
||||
sum += element;
|
||||
callback(null!, element * element);
|
||||
}, function (errors, result) {
|
||||
assert.ok(!errors);
|
||||
|
||||
assert.deepEqual(sum, 15);
|
||||
assert.deepEqual(result, [1, 4, 9, 16, 25]);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('parallel - setTimeout', function (done: () => void) {
|
||||
let elements = [1, 2, 3, 4, 5];
|
||||
let timeouts = [10, 30, 5, 0, 4];
|
||||
let sum = 0;
|
||||
|
||||
parallel(elements, function (element, callback) {
|
||||
setTimeout(function () {
|
||||
sum += element;
|
||||
callback(null!, element * element);
|
||||
}, timeouts.pop());
|
||||
}, function (errors, result) {
|
||||
assert.ok(!errors);
|
||||
|
||||
assert.deepEqual(sum, 15);
|
||||
assert.deepEqual(result, [1, 4, 9, 16, 25]);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('parallel - with error', function (done: () => void) {
|
||||
const elements = [1, 2, 3, 4, 5];
|
||||
const timeouts = [10, 30, 5, 0, 4];
|
||||
let sum = 0;
|
||||
|
||||
parallel(elements, function (element, callback) {
|
||||
setTimeout(function () {
|
||||
if (element === 4) {
|
||||
callback(new Error('error!'), null!);
|
||||
} else {
|
||||
sum += element;
|
||||
callback(null!, element * element);
|
||||
}
|
||||
}, timeouts.pop());
|
||||
}, function (errors, result) {
|
||||
assert.ok(errors);
|
||||
assert.deepEqual(errors, [null, null, null, new Error('error!'), null]);
|
||||
|
||||
assert.deepEqual(sum, 11);
|
||||
assert.deepEqual(result, [1, 4, 9, null, 25]);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -455,7 +455,7 @@ suite('Glob', () => {
|
||||
|
||||
expression = {
|
||||
'**/*.js': {
|
||||
}
|
||||
} as any
|
||||
};
|
||||
|
||||
assert.strictEqual('**/*.js', glob.match(expression, 'test.js', hasSibling));
|
||||
@@ -474,7 +474,7 @@ suite('Glob', () => {
|
||||
'**/*.js': { when: '$(basename).ts' },
|
||||
'**/*.as': true,
|
||||
'**/*.foo': false,
|
||||
'**/*.bananas': { bananas: true }
|
||||
'**/*.bananas': { bananas: true } as any
|
||||
};
|
||||
|
||||
assert.strictEqual('**/*.js', glob.match(expression, 'test.js', hasSibling));
|
||||
@@ -691,7 +691,7 @@ suite('Glob', () => {
|
||||
});
|
||||
|
||||
test('expression with other falsy value', function () {
|
||||
let expr = { '**/*.js': 0 };
|
||||
let expr = { '**/*.js': 0 } as any;
|
||||
|
||||
assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.js');
|
||||
});
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as os from 'os';
|
||||
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
suite('PFS', () => {
|
||||
|
||||
test('writeFile', () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'writefile.txt');
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
return pfs.writeFile(testFile, 'Hello World', null!).then(() => {
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World');
|
||||
|
||||
return pfs.del(parentDir, os.tmpdir());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFile - parallel write on different files works', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile1 = path.join(newDir, 'writefile1.txt');
|
||||
const testFile2 = path.join(newDir, 'writefile2.txt');
|
||||
const testFile3 = path.join(newDir, 'writefile3.txt');
|
||||
const testFile4 = path.join(newDir, 'writefile4.txt');
|
||||
const testFile5 = path.join(newDir, 'writefile5.txt');
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
return Promise.all([
|
||||
pfs.writeFile(testFile1, 'Hello World 1', null!),
|
||||
pfs.writeFile(testFile2, 'Hello World 2', null!),
|
||||
pfs.writeFile(testFile3, 'Hello World 3', null!),
|
||||
pfs.writeFile(testFile4, 'Hello World 4', null!),
|
||||
pfs.writeFile(testFile5, 'Hello World 5', null!)
|
||||
]).then(() => {
|
||||
assert.equal(fs.readFileSync(testFile1), 'Hello World 1');
|
||||
assert.equal(fs.readFileSync(testFile2), 'Hello World 2');
|
||||
assert.equal(fs.readFileSync(testFile3), 'Hello World 3');
|
||||
assert.equal(fs.readFileSync(testFile4), 'Hello World 4');
|
||||
assert.equal(fs.readFileSync(testFile5), 'Hello World 5');
|
||||
|
||||
return pfs.del(parentDir, os.tmpdir());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('writeFile - parallel write on same files works and is sequentalized', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'writefile.txt');
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
return Promise.all([
|
||||
pfs.writeFile(testFile, 'Hello World 1', undefined),
|
||||
pfs.writeFile(testFile, 'Hello World 2', undefined),
|
||||
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', undefined)),
|
||||
pfs.writeFile(testFile, 'Hello World 4', undefined),
|
||||
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', undefined))
|
||||
]).then(() => {
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World 5');
|
||||
|
||||
return pfs.del(parentDir, os.tmpdir());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('rimraf - simple', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
return pfs.rimraf(newDir).then(() => {
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('rimraf - recursive folder structure', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
|
||||
|
||||
return pfs.rimraf(newDir).then(() => {
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('moveIgnoreError', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'extfs', id);
|
||||
|
||||
return pfs.mkdirp(newDir, 493).then(() => {
|
||||
return pfs.renameIgnoreError(path.join(newDir, 'foo'), path.join(newDir, 'bar')).then(() => {
|
||||
|
||||
return pfs.del(parentDir, os.tmpdir());
|
||||
}, error => {
|
||||
assert.fail(error);
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------
|
||||
612
src/vs/base/test/node/pfs/pfs.test.ts
Normal file
612
src/vs/base/test/node/pfs/pfs.test.ts
Normal file
@@ -0,0 +1,612 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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';
|
||||
import * as os from 'os';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as fs from 'fs';
|
||||
import { Readable } from 'stream';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { canNormalize } from 'vs/base/common/normalization';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
|
||||
const chunkSize = 64 * 1024;
|
||||
const readError = 'Error while reading';
|
||||
function toReadable(value: string, throwError?: boolean): Readable {
|
||||
const totalChunks = Math.ceil(value.length / chunkSize);
|
||||
const stringChunks: string[] = [];
|
||||
|
||||
for (let i = 0, j = 0; i < totalChunks; ++i, j += chunkSize) {
|
||||
stringChunks[i] = value.substr(j, chunkSize);
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
return new Readable({
|
||||
read: function () {
|
||||
if (throwError) {
|
||||
this.emit('error', new Error(readError));
|
||||
}
|
||||
|
||||
let res!: string;
|
||||
let canPush = true;
|
||||
while (canPush && (res = stringChunks[counter++])) {
|
||||
canPush = this.push(res);
|
||||
}
|
||||
|
||||
// EOS
|
||||
if (!res) {
|
||||
this.push(null);
|
||||
}
|
||||
},
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
|
||||
suite('PFS', () => {
|
||||
|
||||
test('writeFile', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'writefile.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
await pfs.writeFile(testFile, 'Hello World', (null!));
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World');
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('writeFile - parallel write on different files works', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile1 = path.join(newDir, 'writefile1.txt');
|
||||
const testFile2 = path.join(newDir, 'writefile2.txt');
|
||||
const testFile3 = path.join(newDir, 'writefile3.txt');
|
||||
const testFile4 = path.join(newDir, 'writefile4.txt');
|
||||
const testFile5 = path.join(newDir, 'writefile5.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
await Promise.all([
|
||||
pfs.writeFile(testFile1, 'Hello World 1', (null!)),
|
||||
pfs.writeFile(testFile2, 'Hello World 2', (null!)),
|
||||
pfs.writeFile(testFile3, 'Hello World 3', (null!)),
|
||||
pfs.writeFile(testFile4, 'Hello World 4', (null!)),
|
||||
pfs.writeFile(testFile5, 'Hello World 5', (null!))
|
||||
]);
|
||||
assert.equal(fs.readFileSync(testFile1), 'Hello World 1');
|
||||
assert.equal(fs.readFileSync(testFile2), 'Hello World 2');
|
||||
assert.equal(fs.readFileSync(testFile3), 'Hello World 3');
|
||||
assert.equal(fs.readFileSync(testFile4), 'Hello World 4');
|
||||
assert.equal(fs.readFileSync(testFile5), 'Hello World 5');
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('writeFile - parallel write on same files works and is sequentalized', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'writefile.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
await Promise.all([
|
||||
pfs.writeFile(testFile, 'Hello World 1', undefined),
|
||||
pfs.writeFile(testFile, 'Hello World 2', undefined),
|
||||
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 3', undefined)),
|
||||
pfs.writeFile(testFile, 'Hello World 4', undefined),
|
||||
timeout(10).then(() => pfs.writeFile(testFile, 'Hello World 5', undefined))
|
||||
]);
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World 5');
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('rimraf - simple - unlink', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(newDir);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimraf - simple - move', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(newDir, pfs.RimRafMode.MOVE);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimraf - recursive folder structure - unlink', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(newDir);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimraf - recursive folder structure - move', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(newDir, pfs.RimRafMode.MOVE);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimraf - simple ends with dot - move', async () => {
|
||||
const id = `${uuid.generateUuid()}.`;
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(newDir, pfs.RimRafMode.MOVE);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimraf - simple ends with dot slash/backslash - move', async () => {
|
||||
const id = `${uuid.generateUuid()}.`;
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
await pfs.rimraf(`${newDir}${path.sep}`, pfs.RimRafMode.MOVE);
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimrafSync - swallows file not found error', function () {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
pfs.rimrafSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimrafSync - simple', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
pfs.rimrafSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('rimrafSync - recursive folder structure', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
|
||||
|
||||
pfs.rimrafSync(newDir);
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
});
|
||||
|
||||
test('moveIgnoreError', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
try {
|
||||
await pfs.renameIgnoreError(path.join(newDir, 'foo'), path.join(newDir, 'bar'));
|
||||
return pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
}
|
||||
catch (error) {
|
||||
assert.fail(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
test('copy, move and delete', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const id2 = uuid.generateUuid();
|
||||
const sourceDir = getPathFromAmdModule(require, './fixtures');
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', 'pfs');
|
||||
const targetDir = path.join(parentDir, id);
|
||||
const targetDir2 = path.join(parentDir, id2);
|
||||
|
||||
await pfs.copy(sourceDir, targetDir);
|
||||
|
||||
assert.ok(fs.existsSync(targetDir));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'site.css')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'examples')));
|
||||
assert.ok(fs.statSync(path.join(targetDir, 'examples')).isDirectory());
|
||||
assert.ok(fs.existsSync(path.join(targetDir, 'examples', 'small.jxs')));
|
||||
|
||||
await pfs.move(targetDir, targetDir2);
|
||||
|
||||
assert.ok(!fs.existsSync(targetDir));
|
||||
assert.ok(fs.existsSync(targetDir2));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'site.css')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'examples')));
|
||||
assert.ok(fs.statSync(path.join(targetDir2, 'examples')).isDirectory());
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'examples', 'small.jxs')));
|
||||
|
||||
await pfs.move(path.join(targetDir2, 'index.html'), path.join(targetDir2, 'index_moved.html'));
|
||||
|
||||
assert.ok(!fs.existsSync(path.join(targetDir2, 'index.html')));
|
||||
assert.ok(fs.existsSync(path.join(targetDir2, 'index_moved.html')));
|
||||
|
||||
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
|
||||
assert.ok(!fs.existsSync(parentDir));
|
||||
});
|
||||
|
||||
test('mkdirp', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
return pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('mkdirp cancellation', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
const source = new CancellationTokenSource();
|
||||
|
||||
const mkdirpPromise = pfs.mkdirp(newDir, 493, source.token);
|
||||
source.cancel();
|
||||
|
||||
await mkdirpPromise;
|
||||
|
||||
assert.ok(!fs.existsSync(newDir));
|
||||
|
||||
return pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('readDirsInDir', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder1'));
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder2'));
|
||||
fs.mkdirSync(path.join(newDir, 'somefolder3'));
|
||||
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
|
||||
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
|
||||
|
||||
const result = await pfs.readDirsInDir(newDir);
|
||||
assert.equal(result.length, 3);
|
||||
assert.ok(result.indexOf('somefolder1') !== -1);
|
||||
assert.ok(result.indexOf('somefolder2') !== -1);
|
||||
assert.ok(result.indexOf('somefolder3') !== -1);
|
||||
|
||||
await pfs.rimraf(newDir);
|
||||
});
|
||||
|
||||
test('stat link', async () => {
|
||||
if (isWindows) {
|
||||
return Promise.resolve(); // Symlinks are not the same on win, and we can not create them programitically without admin privileges
|
||||
}
|
||||
|
||||
const id1 = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id1);
|
||||
const directory = path.join(parentDir, 'pfs', id1);
|
||||
|
||||
const id2 = uuid.generateUuid();
|
||||
const symbolicLink = path.join(parentDir, 'pfs', id2);
|
||||
|
||||
await pfs.mkdirp(directory, 493);
|
||||
|
||||
fs.symlinkSync(directory, symbolicLink);
|
||||
|
||||
let statAndIsLink = await pfs.statLink(directory);
|
||||
assert.ok(!statAndIsLink!.isSymbolicLink);
|
||||
|
||||
statAndIsLink = await pfs.statLink(symbolicLink);
|
||||
assert.ok(statAndIsLink!.isSymbolicLink);
|
||||
|
||||
pfs.rimrafSync(directory);
|
||||
});
|
||||
|
||||
test('readdir', async () => {
|
||||
if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id, 'öäü');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
const children = await pfs.readdir(path.join(parentDir, 'pfs', id));
|
||||
assert.equal(children.some(n => n === 'öäü'), true); // Mac always converts to NFD, so
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
}
|
||||
});
|
||||
|
||||
test('writeFile (string)', async () => {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
return testWriteFileAndFlush(smallData, smallData, bigData, bigData);
|
||||
});
|
||||
|
||||
test('writeFile (Buffer)', async () => {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
return testWriteFileAndFlush(Buffer.from(smallData), smallData, Buffer.from(bigData), bigData);
|
||||
});
|
||||
|
||||
test('writeFile (UInt8Array)', async () => {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
return testWriteFileAndFlush(VSBuffer.fromString(smallData).buffer, smallData, VSBuffer.fromString(bigData).buffer, bigData);
|
||||
});
|
||||
|
||||
test('writeFile (stream)', async () => {
|
||||
const smallData = 'Hello World';
|
||||
const bigData = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
return testWriteFileAndFlush(toReadable(smallData), smallData, toReadable(bigData), bigData);
|
||||
});
|
||||
|
||||
async function testWriteFileAndFlush(
|
||||
smallData: string | Buffer | NodeJS.ReadableStream | Uint8Array,
|
||||
smallDataValue: string,
|
||||
bigData: string | Buffer | NodeJS.ReadableStream | Uint8Array,
|
||||
bigDataValue: string
|
||||
): Promise<void> {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
await pfs.writeFile(testFile, smallData);
|
||||
assert.equal(fs.readFileSync(testFile), smallDataValue);
|
||||
|
||||
await pfs.writeFile(testFile, bigData);
|
||||
assert.equal(fs.readFileSync(testFile), bigDataValue);
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
}
|
||||
|
||||
test('writeFile (file stream)', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const sourceFile = getPathFromAmdModule(require, './fixtures/index.html');
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
await pfs.writeFile(testFile, fs.createReadStream(sourceFile));
|
||||
assert.equal(fs.readFileSync(testFile).toString(), fs.readFileSync(sourceFile).toString());
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFile (string, error handling)', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
let expectedError: Error | undefined;
|
||||
try {
|
||||
await pfs.writeFile(testFile, 'Hello World');
|
||||
} catch (error) {
|
||||
expectedError = error;
|
||||
}
|
||||
|
||||
assert.ok(expectedError);
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFile (stream, error handling EISDIR)', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
const readable = toReadable('Hello World');
|
||||
|
||||
let expectedError: Error | undefined;
|
||||
try {
|
||||
await pfs.writeFile(testFile, readable);
|
||||
} catch (error) {
|
||||
expectedError = error;
|
||||
}
|
||||
|
||||
if (!expectedError || (<any>expectedError).code !== 'EISDIR') {
|
||||
return Promise.reject(new Error('Expected EISDIR error for writing to folder but got: ' + (expectedError ? (<any>expectedError).code : 'no error')));
|
||||
}
|
||||
|
||||
// verify that the stream is still consumable (for https://github.com/Microsoft/vscode/issues/42542)
|
||||
assert.equal(readable.read(), 'Hello World');
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFile (stream, error handling READERROR)', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
let expectedError: Error | undefined;
|
||||
try {
|
||||
await pfs.writeFile(testFile, toReadable('Hello World', true /* throw error */));
|
||||
} catch (error) {
|
||||
expectedError = error;
|
||||
}
|
||||
|
||||
if (!expectedError || expectedError.message !== readError) {
|
||||
return Promise.reject(new Error('Expected error for writing to folder'));
|
||||
}
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFile (stream, error handling EACCES)', async () => {
|
||||
if (isLinux) {
|
||||
return Promise.resolve(); // somehow this test fails on Linux in our TFS builds
|
||||
}
|
||||
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.writeFileSync(testFile, '');
|
||||
fs.chmodSync(testFile, 33060); // make readonly
|
||||
|
||||
let expectedError: Error | undefined;
|
||||
try {
|
||||
await pfs.writeFile(testFile, toReadable('Hello World'));
|
||||
} catch (error) {
|
||||
expectedError = error;
|
||||
}
|
||||
|
||||
if (!expectedError || !((<any>expectedError).code !== 'EACCES' || (<any>expectedError).code !== 'EPERM')) {
|
||||
return Promise.reject(new Error('Expected EACCES/EPERM error for writing to folder but got: ' + (expectedError ? (<any>expectedError).code : 'no error')));
|
||||
}
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFile (file stream, error handling)', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const sourceFile = getPathFromAmdModule(require, './fixtures/index.html');
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
fs.mkdirSync(testFile); // this will trigger an error because testFile is now a directory!
|
||||
|
||||
let expectedError: Error | undefined;
|
||||
try {
|
||||
await pfs.writeFile(testFile, fs.createReadStream(sourceFile));
|
||||
} catch (error) {
|
||||
expectedError = error;
|
||||
}
|
||||
|
||||
if (!expectedError) {
|
||||
return Promise.reject(new Error('Expected error for writing to folder'));
|
||||
}
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
|
||||
test('writeFileSync', async () => {
|
||||
const id = uuid.generateUuid();
|
||||
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
|
||||
const newDir = path.join(parentDir, 'pfs', id);
|
||||
const testFile = path.join(newDir, 'flushed.txt');
|
||||
|
||||
await pfs.mkdirp(newDir, 493);
|
||||
|
||||
assert.ok(fs.existsSync(newDir));
|
||||
|
||||
pfs.writeFileSync(testFile, 'Hello World');
|
||||
assert.equal(fs.readFileSync(testFile), 'Hello World');
|
||||
|
||||
const largeString = (new Array(100 * 1024)).join('Large String\n');
|
||||
|
||||
pfs.writeFileSync(testFile, largeString);
|
||||
assert.equal(fs.readFileSync(testFile), largeString);
|
||||
|
||||
await pfs.rimraf(parentDir);
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,7 @@ import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { tmpdir } from 'os';
|
||||
import { equal, ok } from 'assert';
|
||||
import { mkdirp, del, writeFile, exists, unlink } from 'vs/base/node/pfs';
|
||||
import { mkdirp, writeFile, exists, unlink, rimraf, RimRafMode } from 'vs/base/node/pfs';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
@@ -92,7 +92,7 @@ suite('Storage Library', () => {
|
||||
equal(deletePromiseResolved, true);
|
||||
|
||||
await storage.close();
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('external changes', async () => {
|
||||
@@ -148,7 +148,7 @@ suite('Storage Library', () => {
|
||||
equal(changes.size, 0);
|
||||
|
||||
await storage.close();
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('close flushes data', async () => {
|
||||
@@ -202,7 +202,7 @@ suite('Storage Library', () => {
|
||||
ok(!storage.get('bar'));
|
||||
|
||||
await storage.close();
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('conflicting updates', async () => {
|
||||
@@ -244,7 +244,7 @@ suite('Storage Library', () => {
|
||||
ok(setAndDeletePromiseResolved);
|
||||
|
||||
await storage.close();
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('corrupt DB recovers', async () => {
|
||||
@@ -274,7 +274,7 @@ suite('Storage Library', () => {
|
||||
equal(storage.get('foo'), 'bar');
|
||||
|
||||
await storage.close();
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -372,7 +372,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await testDBBasics(join(storageDir, 'storage.db'));
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('basics (open multiple times)', async () => {
|
||||
@@ -383,7 +383,7 @@ suite('SQLite Storage Library', () => {
|
||||
await testDBBasics(join(storageDir, 'storage.db'));
|
||||
await testDBBasics(join(storageDir, 'storage.db'));
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('basics (corrupt DB falls back to empty DB)', async () => {
|
||||
@@ -401,7 +401,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
ok(expectedError);
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('basics (corrupt DB restores from previous backup)', async () => {
|
||||
@@ -439,7 +439,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
equal(recoveryCalled, false);
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('basics (corrupt DB falls back to empty DB if backup is corrupt)', async () => {
|
||||
@@ -468,7 +468,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await testDBBasics(storagePath);
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('basics (DB that becomes corrupt during runtime stores all state from cache on close)', async () => {
|
||||
@@ -536,7 +536,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
equal(recoveryCalled, false);
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('real world example', async function () {
|
||||
@@ -627,7 +627,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('very large item value', async function () {
|
||||
@@ -682,7 +682,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('multiple concurrent writes execute in sequence', async () => {
|
||||
@@ -739,7 +739,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('lots of INSERT & DELETE (below inline max)', async () => {
|
||||
@@ -771,7 +771,7 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
|
||||
test('lots of INSERT & DELETE (above inline max)', async () => {
|
||||
@@ -803,6 +803,6 @@ suite('SQLite Storage Library', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
await del(storageDir, tmpdir());
|
||||
await rimraf(storageDir, RimRafMode.MOVE);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { tmpdir } from 'os';
|
||||
import { mkdirp, del } from 'vs/base/node/pfs';
|
||||
import { mkdirp, rimraf, RimRafMode } from 'vs/base/node/pfs';
|
||||
|
||||
export interface ITestFileResult {
|
||||
testFile: string;
|
||||
@@ -22,7 +22,7 @@ export function testFile(folder: string, file: string): Promise<ITestFileResult>
|
||||
return mkdirp(newDir, 493).then(() => {
|
||||
return {
|
||||
testFile,
|
||||
cleanUp: () => del(parentDir, tmpdir())
|
||||
} as ITestFileResult;
|
||||
cleanUp: () => rimraf(parentDir, RimRafMode.MOVE)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user