chore(vscode): update to 1.53.2

These conflicts will be resolved in the following commits. We do it this way so
that PR review is possible.
This commit is contained in:
Joe Previte
2021-02-25 11:27:27 -07:00
1900 changed files with 83066 additions and 64589 deletions

View File

@@ -1,413 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { VSBuffer, bufferToReadable, readableToBuffer, bufferToStream, streamToBuffer, newWriteableBufferStream, bufferedStreamToBuffer } from 'vs/base/common/buffer';
import { timeout } from 'vs/base/common/async';
import { peekStream } from 'vs/base/common/stream';
suite('Buffer', () => {
test('issue #71993 - VSBuffer#toString returns numbers', () => {
const data = new Uint8Array([1, 2, 3, 'h'.charCodeAt(0), 'i'.charCodeAt(0), 4, 5]).buffer;
const buffer = VSBuffer.wrap(new Uint8Array(data, 3, 2));
assert.deepEqual(buffer.toString(), 'hi');
});
test('bufferToReadable / readableToBuffer', () => {
const content = 'Hello World';
const readable = bufferToReadable(VSBuffer.fromString(content));
assert.equal(readableToBuffer(readable).toString(), content);
});
test('bufferToStream / streamToBuffer', async () => {
const content = 'Hello World';
const stream = bufferToStream(VSBuffer.fromString(content));
assert.equal((await streamToBuffer(stream)).toString(), content);
});
test('bufferedStreamToBuffer', async () => {
const content = 'Hello World';
const stream = await peekStream(bufferToStream(VSBuffer.fromString(content)), 1);
assert.equal((await bufferedStreamToBuffer(stream)).toString(), content);
});
test('bufferWriteableStream - basics (no error)', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
assert.equal(chunks.length, 2);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(chunks[1].toString(), 'World');
assert.equal(ended, true);
assert.equal(errors.length, 0);
});
test('bufferWriteableStream - basics (error)', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(new Error());
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(ended, true);
assert.equal(errors.length, 1);
});
test('bufferWriteableStream - buffers data when no listener', async () => {
const stream = newWriteableBufferStream();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'HelloWorld');
assert.equal(ended, true);
assert.equal(errors.length, 0);
});
test('bufferWriteableStream - buffers errors when no listener', async () => {
const stream = newWriteableBufferStream();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.error(new Error());
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
stream.end();
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(ended, true);
assert.equal(errors.length, 1);
});
test('bufferWriteableStream - buffers end when no listener', async () => {
const stream = newWriteableBufferStream();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
let ended = false;
stream.on('end', () => {
ended = true;
});
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'HelloWorld');
assert.equal(ended, true);
assert.equal(errors.length, 0);
});
test('bufferWriteableStream - nothing happens after end()', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
let dataCalledAfterEnd = false;
stream.on('data', data => {
dataCalledAfterEnd = true;
});
let errorCalledAfterEnd = false;
stream.on('error', error => {
errorCalledAfterEnd = true;
});
let endCalledAfterEnd = false;
stream.on('end', () => {
endCalledAfterEnd = true;
});
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.error(new Error());
await timeout(0);
stream.end(VSBuffer.fromString('World'));
assert.equal(dataCalledAfterEnd, false);
assert.equal(errorCalledAfterEnd, false);
assert.equal(endCalledAfterEnd, false);
assert.equal(chunks.length, 2);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(chunks[1].toString(), 'World');
});
test('bufferWriteableStream - pause/resume (simple)', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
stream.pause();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
assert.equal(chunks.length, 0);
assert.equal(errors.length, 0);
assert.equal(ended, false);
stream.resume();
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'HelloWorld');
assert.equal(ended, true);
assert.equal(errors.length, 0);
});
test('bufferWriteableStream - pause/resume (pause after first write)', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
stream.pause();
await timeout(0);
stream.end(VSBuffer.fromString('World'));
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(errors.length, 0);
assert.equal(ended, false);
stream.resume();
assert.equal(chunks.length, 2);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(chunks[1].toString(), 'World');
assert.equal(ended, true);
assert.equal(errors.length, 0);
});
test('bufferWriteableStream - pause/resume (error)', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
stream.pause();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(new Error());
assert.equal(chunks.length, 0);
assert.equal(ended, false);
assert.equal(errors.length, 0);
stream.resume();
assert.equal(chunks.length, 1);
assert.equal(chunks[0].toString(), 'Hello');
assert.equal(ended, true);
assert.equal(errors.length, 1);
});
test('bufferWriteableStream - destroy', async () => {
const stream = newWriteableBufferStream();
let chunks: VSBuffer[] = [];
stream.on('data', data => {
chunks.push(data);
});
let ended = false;
stream.on('end', () => {
ended = true;
});
let errors: Error[] = [];
stream.on('error', error => {
errors.push(error);
});
stream.destroy();
await timeout(0);
stream.write(VSBuffer.fromString('Hello'));
await timeout(0);
stream.end(VSBuffer.fromString('World'));
assert.equal(chunks.length, 0);
assert.equal(ended, false);
assert.equal(errors.length, 0);
});
test('Performance issue with VSBuffer#slice #76076', function () {
// Buffer#slice creates a view
{
const buff = Buffer.from([10, 20, 30, 40]);
const b2 = buff.slice(1, 3);
assert.equal(buff[1], 20);
assert.equal(b2[0], 20);
buff[1] = 17; // modify buff AND b2
assert.equal(buff[1], 17);
assert.equal(b2[0], 17);
}
// TypedArray#slice creates a copy
{
const unit = new Uint8Array([10, 20, 30, 40]);
const u2 = unit.slice(1, 3);
assert.equal(unit[1], 20);
assert.equal(u2[0], 20);
unit[1] = 17; // modify unit, NOT b2
assert.equal(unit[1], 17);
assert.equal(u2[0], 20);
}
// TypedArray#subarray creates a view
{
const unit = new Uint8Array([10, 20, 30, 40]);
const u2 = unit.subarray(1, 3);
assert.equal(unit[1], 20);
assert.equal(u2[0], 20);
unit[1] = 17; // modify unit AND b2
assert.equal(unit[1], 17);
assert.equal(u2[0], 17);
}
});
});

View File

@@ -1,48 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { getFirstFrame } from 'vs/base/common/console';
import { normalize } from 'vs/base/common/path';
suite('Console', () => {
test('getFirstFrame', () => {
let stack = 'at vscode.commands.registerCommand (/Users/someone/Desktop/test-ts/out/src/extension.js:18:17)';
let frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17';
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17';
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js');
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at e.$executeContributedCommand(c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17)';
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js');
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
stack = 'at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17\nat /Users/someone/Desktop/test-ts/out/src/other.js:28:27\nat /Users/someone/Desktop/test-ts/out/src/more.js:38:37';
frame = getFirstFrame(stack)!;
assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js'));
assert.equal(frame.line, 18);
assert.equal(frame.column, 17);
});
});

View File

@@ -4,24 +4,29 @@
*--------------------------------------------------------------------------------------------*/
import { checksum } from 'vs/base/node/crypto';
import { generateUuid } from 'vs/base/common/uuid';
import { join } from 'vs/base/common/path';
import { tmpdir } from 'os';
import { mkdirp, rimraf, RimRafMode, writeFile } from 'vs/base/node/pfs';
import { mkdirp, rimraf, writeFile } from 'vs/base/node/pfs';
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
suite('Crypto', () => {
let testDir: string;
setup(function () {
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'crypto');
return mkdirp(testDir);
});
teardown(function () {
return rimraf(testDir);
});
test('checksum', async () => {
const id = generateUuid();
const testDir = join(tmpdir(), 'vsctests', id);
const testFile = join(testDir, 'checksum.txt');
await mkdirp(testDir);
await writeFile(testFile, 'Hello World');
await checksum(testFile, '0a4d55a8d778e5022fab701977c5d840bbc486d0');
await rimraf(testDir, RimRafMode.MOVE);
});
});

View File

@@ -4,19 +4,19 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as decoder from 'vs/base/node/decoder';
import { LineDecoder } from 'vs/base/node/decoder';
suite('Decoder', () => {
test('decoding', () => {
const lineDecoder = new decoder.LineDecoder();
const lineDecoder = new LineDecoder();
let res = lineDecoder.write(Buffer.from('hello'));
assert.equal(res.length, 0);
assert.strictEqual(res.length, 0);
res = lineDecoder.write(Buffer.from('\nworld'));
assert.equal(res[0], 'hello');
assert.equal(res.length, 1);
assert.strictEqual(res[0], 'hello');
assert.strictEqual(res.length, 1);
assert.equal(lineDecoder.end(), 'world');
assert.strictEqual(lineDecoder.end(), 'world');
});
});
});

View File

@@ -4,70 +4,52 @@
*--------------------------------------------------------------------------------------------*/
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 { tmpdir } from 'os';
import { mkdirp, rimraf } from 'vs/base/node/pfs';
import { realcaseSync, realpath, realpathSync } from 'vs/base/node/extpath';
import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils';
suite('Extpath', () => {
flakySuite('Extpath', () => {
let testDir: string;
setup(() => {
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'extpath');
return mkdirp(testDir, 493);
});
teardown(() => {
return rimraf(testDir);
});
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 upper = testDir.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);
assert.notStrictEqual(real, upper);
assert.strictEqual(real.toUpperCase(), upper);
assert.strictEqual(real, testDir);
}
}
// linux, unix, etc. -> assume case sensitive file system
else {
const real = realcaseSync(newDir);
assert.equal(real, newDir);
const real = realcaseSync(testDir);
assert.strictEqual(real, testDir);
}
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);
const realpathVal = await realpath(testDir);
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);
test('realpathSync', () => {
const realpath = realpathSync(testDir);
assert.ok(realpath);
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -2,22 +2,21 @@
* 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 { getMachineId } from 'vs/base/node/id';
import { getMac } from 'vs/base/node/macAddress';
import { flakySuite } from 'vs/base/test/node/testUtils';
suite('ID', () => {
flakySuite('ID', () => {
test('getMachineId', function () {
this.timeout(20000);
return getMachineId().then(id => {
assert.ok(id);
});
test('getMachineId', async function () {
const id = await getMachineId();
assert.ok(id);
});
test('getMac', () => {
return getMac().then(macAddress => {
assert.ok(/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(macAddress), `Expected a MAC address, got: ${macAddress}`);
});
test('getMac', async () => {
const macAddress = await getMac();
assert.ok(/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(macAddress), `Expected a MAC address, got: ${macAddress}`);
});
});
});

View File

@@ -2,36 +2,30 @@
* 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 platform from 'vs/base/common/platform';
import { isLinux } from 'vs/base/common/platform';
suite('Keytar', () => {
test('loads and is functional', function (done) {
if (platform.isLinux) {
// Skip test due to set up issue with Travis.
this.skip();
return;
}
(async () => {
const keytar = await import('keytar');
const name = `VSCode Test ${Math.floor(Math.random() * 1e9)}`;
(isLinux ? test.skip : test)('loads and is functional', async () => { // TODO@RMacfarlane test seems to fail on Linux (Error: Unknown or unsupported transport 'disabled' for address 'disabled:')
const keytar = await import('keytar');
const name = `VSCode Test ${Math.floor(Math.random() * 1e9)}`;
try {
await keytar.setPassword(name, 'foo', 'bar');
assert.strictEqual(await keytar.findPassword(name), 'bar');
assert.strictEqual((await keytar.findCredentials(name)).length, 1);
assert.strictEqual(await keytar.getPassword(name, 'foo'), 'bar');
await keytar.deletePassword(name, 'foo');
assert.strictEqual(await keytar.getPassword(name, 'foo'), null);
} catch (err) {
// try to clean up
try {
await keytar.setPassword(name, 'foo', 'bar');
assert.equal(await keytar.findPassword(name), 'bar');
assert.equal((await keytar.findCredentials(name)).length, 1);
assert.equal(await keytar.getPassword(name, 'foo'), 'bar');
await keytar.deletePassword(name, 'foo');
assert.equal(await keytar.getPassword(name, 'foo'), undefined);
} catch (err) {
// try to clean up
try {
await keytar.deletePassword(name, 'foo');
} finally {
// eslint-disable-next-line no-unsafe-finally
throw err;
}
} finally {
// eslint-disable-next-line no-unsafe-finally
throw err;
}
})().then(done, done);
}
});
});

View File

@@ -1,819 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// NOTE: VSCode's copy of nodejs path library to be usable in common (non-node) namespace
// Copied from: https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import { isWindows } from 'vs/base/common/platform';
import * as process from 'vs/base/common/process';
suite('Paths (Node Implementation)', () => {
test('join', () => {
const failures = [] as string[];
const backslashRE = /\\/g;
const joinTests: any = [
[[path.posix.join, path.win32.join],
// arguments result
[[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'],
[[], '.'],
[['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'],
[['/foo', '../../../bar'], '/bar'],
[['foo', '../../../bar'], '../../bar'],
[['foo/', '../../../bar'], '../../bar'],
[['foo/x', '../../../bar'], '../bar'],
[['foo/x', './bar'], 'foo/x/bar'],
[['foo/x/', './bar'], 'foo/x/bar'],
[['foo/x/', '.', 'bar'], 'foo/x/bar'],
[['./'], './'],
[['.', './'], './'],
[['.', '.', '.'], '.'],
[['.', './', '.'], '.'],
[['.', '/./', '.'], '.'],
[['.', '/////./', '.'], '.'],
[['.'], '.'],
[['', '.'], '.'],
[['', 'foo'], 'foo'],
[['foo', '/bar'], 'foo/bar'],
[['', '/foo'], '/foo'],
[['', '', '/foo'], '/foo'],
[['', '', 'foo'], 'foo'],
[['foo', ''], 'foo'],
[['foo/', ''], 'foo/'],
[['foo', '', '/bar'], 'foo/bar'],
[['./', '..', '/foo'], '../foo'],
[['./', '..', '..', '/foo'], '../../foo'],
[['.', '..', '..', '/foo'], '../../foo'],
[['', '..', '..', '/foo'], '../../foo'],
[['/'], '/'],
[['/', '.'], '/'],
[['/', '..'], '/'],
[['/', '..', '..'], '/'],
[[''], '.'],
[['', ''], '.'],
[[' /foo'], ' /foo'],
[[' ', 'foo'], ' /foo'],
[[' ', '.'], ' '],
[[' ', '/'], ' /'],
[[' ', ''], ' '],
[['/', 'foo'], '/foo'],
[['/', '/foo'], '/foo'],
[['/', '//foo'], '/foo'],
[['/', '', '/foo'], '/foo'],
[['', '/', 'foo'], '/foo'],
[['', '/', '/foo'], '/foo']
]
]
];
// Windows-specific join tests
joinTests.push([
path.win32.join,
joinTests[0][1].slice(0).concat(
[// arguments result
// UNC path expected
[['//foo/bar'], '\\\\foo\\bar\\'],
[['\\/foo/bar'], '\\\\foo\\bar\\'],
[['\\\\foo/bar'], '\\\\foo\\bar\\'],
// UNC path expected - server and share separate
[['//foo', 'bar'], '\\\\foo\\bar\\'],
[['//foo/', 'bar'], '\\\\foo\\bar\\'],
[['//foo', '/bar'], '\\\\foo\\bar\\'],
// UNC path expected - questionable
[['//foo', '', 'bar'], '\\\\foo\\bar\\'],
[['//foo/', '', 'bar'], '\\\\foo\\bar\\'],
[['//foo/', '', '/bar'], '\\\\foo\\bar\\'],
// UNC path expected - even more questionable
[['', '//foo', 'bar'], '\\\\foo\\bar\\'],
[['', '//foo/', 'bar'], '\\\\foo\\bar\\'],
[['', '//foo/', '/bar'], '\\\\foo\\bar\\'],
// No UNC path expected (no double slash in first component)
[['\\', 'foo/bar'], '\\foo\\bar'],
[['\\', '/foo/bar'], '\\foo\\bar'],
[['', '/', '/foo/bar'], '\\foo\\bar'],
// No UNC path expected (no non-slashes in first component -
// questionable)
[['//', 'foo/bar'], '\\foo\\bar'],
[['//', '/foo/bar'], '\\foo\\bar'],
[['\\\\', '/', '/foo/bar'], '\\foo\\bar'],
[['//'], '\\'],
// No UNC path expected (share name missing - questionable).
[['//foo'], '\\foo'],
[['//foo/'], '\\foo\\'],
[['//foo', '/'], '\\foo\\'],
[['//foo', '', '/'], '\\foo\\'],
// No UNC path expected (too many leading slashes - questionable)
[['///foo/bar'], '\\foo\\bar'],
[['////foo', 'bar'], '\\foo\\bar'],
[['\\\\\\/foo/bar'], '\\foo\\bar'],
// Drive-relative vs drive-absolute paths. This merely describes the
// status quo, rather than being obviously right
[['c:'], 'c:.'],
[['c:.'], 'c:.'],
[['c:', ''], 'c:.'],
[['', 'c:'], 'c:.'],
[['c:.', '/'], 'c:.\\'],
[['c:.', 'file'], 'c:file'],
[['c:', '/'], 'c:\\'],
[['c:', 'file'], 'c:\\file']
]
)
]);
joinTests.forEach((test: any[]) => {
if (!Array.isArray(test[0])) {
test[0] = [test[0]];
}
test[0].forEach((join: any) => {
test[1].forEach((test: any) => {
const actual = join.apply(null, test[0]);
const expected = test[1];
// For non-Windows specific tests with the Windows join(), we need to try
// replacing the slashes since the non-Windows specific tests' `expected`
// use forward slashes
let actualAlt;
let os;
if (join === path.win32.join) {
actualAlt = actual.replace(backslashRE, '/');
os = 'win32';
} else {
os = 'posix';
}
const message =
`path.${os}.join(${test[0].map(JSON.stringify).join(',')})\n expect=${JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`;
if (actual !== expected && actualAlt !== expected) {
failures.push(`\n${message}`);
}
});
});
});
assert.strictEqual(failures.length, 0, failures.join(''));
});
test('dirname', () => {
assert.strictEqual(path.dirname(path.normalize(__filename)).substr(-9),
isWindows ? 'test\\node' : 'test/node');
assert.strictEqual(path.posix.dirname('/a/b/'), '/a');
assert.strictEqual(path.posix.dirname('/a/b'), '/a');
assert.strictEqual(path.posix.dirname('/a'), '/');
assert.strictEqual(path.posix.dirname(''), '.');
assert.strictEqual(path.posix.dirname('/'), '/');
assert.strictEqual(path.posix.dirname('////'), '/');
assert.strictEqual(path.posix.dirname('//a'), '//');
assert.strictEqual(path.posix.dirname('foo'), '.');
assert.strictEqual(path.win32.dirname('c:\\'), 'c:\\');
assert.strictEqual(path.win32.dirname('c:\\foo'), 'c:\\');
assert.strictEqual(path.win32.dirname('c:\\foo\\'), 'c:\\');
assert.strictEqual(path.win32.dirname('c:\\foo\\bar'), 'c:\\foo');
assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\'), 'c:\\foo');
assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar');
assert.strictEqual(path.win32.dirname('\\'), '\\');
assert.strictEqual(path.win32.dirname('\\foo'), '\\');
assert.strictEqual(path.win32.dirname('\\foo\\'), '\\');
assert.strictEqual(path.win32.dirname('\\foo\\bar'), '\\foo');
assert.strictEqual(path.win32.dirname('\\foo\\bar\\'), '\\foo');
assert.strictEqual(path.win32.dirname('\\foo\\bar\\baz'), '\\foo\\bar');
assert.strictEqual(path.win32.dirname('c:'), 'c:');
assert.strictEqual(path.win32.dirname('c:foo'), 'c:');
assert.strictEqual(path.win32.dirname('c:foo\\'), 'c:');
assert.strictEqual(path.win32.dirname('c:foo\\bar'), 'c:foo');
assert.strictEqual(path.win32.dirname('c:foo\\bar\\'), 'c:foo');
assert.strictEqual(path.win32.dirname('c:foo\\bar\\baz'), 'c:foo\\bar');
assert.strictEqual(path.win32.dirname('file:stream'), '.');
assert.strictEqual(path.win32.dirname('dir\\file:stream'), 'dir');
assert.strictEqual(path.win32.dirname('\\\\unc\\share'),
'\\\\unc\\share');
assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo'),
'\\\\unc\\share\\');
assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\'),
'\\\\unc\\share\\');
assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar'),
'\\\\unc\\share\\foo');
assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'),
'\\\\unc\\share\\foo');
assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'),
'\\\\unc\\share\\foo\\bar');
assert.strictEqual(path.win32.dirname('/a/b/'), '/a');
assert.strictEqual(path.win32.dirname('/a/b'), '/a');
assert.strictEqual(path.win32.dirname('/a'), '/');
assert.strictEqual(path.win32.dirname(''), '.');
assert.strictEqual(path.win32.dirname('/'), '/');
assert.strictEqual(path.win32.dirname('////'), '/');
assert.strictEqual(path.win32.dirname('foo'), '.');
// Tests from VSCode
function assertDirname(p: string, expected: string, win = false) {
const actual = win ? path.win32.dirname(p) : path.posix.dirname(p);
if (actual !== expected) {
assert.fail(`${p}: expected: ${expected}, ours: ${actual}`);
}
}
assertDirname('foo/bar', 'foo');
assertDirname('foo\\bar', 'foo', true);
assertDirname('/foo/bar', '/foo');
assertDirname('\\foo\\bar', '\\foo', true);
assertDirname('/foo', '/');
assertDirname('\\foo', '\\', true);
assertDirname('/', '/');
assertDirname('\\', '\\', true);
assertDirname('foo', '.');
assertDirname('f', '.');
assertDirname('f/', '.');
assertDirname('/folder/', '/');
assertDirname('c:\\some\\file.txt', 'c:\\some', true);
assertDirname('c:\\some', 'c:\\', true);
assertDirname('c:\\', 'c:\\', true);
assertDirname('c:', 'c:', true);
assertDirname('\\\\server\\share\\some\\path', '\\\\server\\share\\some', true);
assertDirname('\\\\server\\share\\some', '\\\\server\\share\\', true);
assertDirname('\\\\server\\share\\', '\\\\server\\share\\', true);
});
test('extname', () => {
const failures = [] as string[];
const slashRE = /\//g;
[
[__filename, '.js'],
['', ''],
['/path/to/file', ''],
['/path/to/file.ext', '.ext'],
['/path.to/file.ext', '.ext'],
['/path.to/file', ''],
['/path.to/.file', ''],
['/path.to/.file.ext', '.ext'],
['/path/to/f.ext', '.ext'],
['/path/to/..ext', '.ext'],
['/path/to/..', ''],
['file', ''],
['file.ext', '.ext'],
['.file', ''],
['.file.ext', '.ext'],
['/file', ''],
['/file.ext', '.ext'],
['/.file', ''],
['/.file.ext', '.ext'],
['.path/file.ext', '.ext'],
['file.ext.ext', '.ext'],
['file.', '.'],
['.', ''],
['./', ''],
['.file.ext', '.ext'],
['.file', ''],
['.file.', '.'],
['.file..', '.'],
['..', ''],
['../', ''],
['..file.ext', '.ext'],
['..file', '.file'],
['..file.', '.'],
['..file..', '.'],
['...', '.'],
['...ext', '.ext'],
['....', '.'],
['file.ext/', '.ext'],
['file.ext//', '.ext'],
['file/', ''],
['file//', ''],
['file./', '.'],
['file.//', '.'],
].forEach((test) => {
const expected = test[1];
[path.posix.extname, path.win32.extname].forEach((extname) => {
let input = test[0];
let os;
if (extname === path.win32.extname) {
input = input.replace(slashRE, '\\');
os = 'win32';
} else {
os = 'posix';
}
const actual = extname(input);
const message = `path.${os}.extname(${JSON.stringify(input)})\n expect=${JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`;
if (actual !== expected) {
failures.push(`\n${message}`);
}
});
{
const input = `C:${test[0].replace(slashRE, '\\')}`;
const actual = path.win32.extname(input);
const message = `path.win32.extname(${JSON.stringify(input)})\n expect=${JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`;
if (actual !== expected) {
failures.push(`\n${message}`);
}
}
});
assert.strictEqual(failures.length, 0, failures.join(''));
// On Windows, backslash is a path separator.
assert.strictEqual(path.win32.extname('.\\'), '');
assert.strictEqual(path.win32.extname('..\\'), '');
assert.strictEqual(path.win32.extname('file.ext\\'), '.ext');
assert.strictEqual(path.win32.extname('file.ext\\\\'), '.ext');
assert.strictEqual(path.win32.extname('file\\'), '');
assert.strictEqual(path.win32.extname('file\\\\'), '');
assert.strictEqual(path.win32.extname('file.\\'), '.');
assert.strictEqual(path.win32.extname('file.\\\\'), '.');
// On *nix, backslash is a valid name component like any other character.
assert.strictEqual(path.posix.extname('.\\'), '');
assert.strictEqual(path.posix.extname('..\\'), '.\\');
assert.strictEqual(path.posix.extname('file.ext\\'), '.ext\\');
assert.strictEqual(path.posix.extname('file.ext\\\\'), '.ext\\\\');
assert.strictEqual(path.posix.extname('file\\'), '');
assert.strictEqual(path.posix.extname('file\\\\'), '');
assert.strictEqual(path.posix.extname('file.\\'), '.\\');
assert.strictEqual(path.posix.extname('file.\\\\'), '.\\\\');
// Tests from VSCode
assert.equal(path.extname('far.boo'), '.boo');
assert.equal(path.extname('far.b'), '.b');
assert.equal(path.extname('far.'), '.');
assert.equal(path.extname('far.boo/boo.far'), '.far');
assert.equal(path.extname('far.boo/boo'), '');
});
test('resolve', () => {
const failures = [] as string[];
const slashRE = /\//g;
const backslashRE = /\\/g;
const resolveTests = [
[path.win32.resolve,
// arguments result
[[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'],
[['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'],
[['c:/ignore', 'c:/some/file'], 'c:\\some\\file'],
[['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'],
[['.'], process.cwd()],
[['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'],
[['c:/', '//'], 'c:\\'],
[['c:/', '//dir'], 'c:\\dir'],
[['c:/', '//server/share'], '\\\\server\\share\\'],
[['c:/', '//server//share'], '\\\\server\\share\\'],
[['c:/', '///some//dir'], 'c:\\some\\dir'],
[['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'],
'C:\\foo\\tmp.3\\cycles\\root.js']
]
],
[path.posix.resolve,
// arguments result
[[['/var/lib', '../', 'file/'], '/var/file'],
[['/var/lib', '/../', 'file/'], '/file'],
[['a/b/c/', '../../..'], process.cwd()],
[['.'], process.cwd()],
[['/some/dir', '.', '/absolute/'], '/absolute'],
[['/foo/tmp.3/', '../tmp.3/cycles/root.js'], '/foo/tmp.3/cycles/root.js']
]
]
];
resolveTests.forEach((test) => {
const resolve = test[0];
//@ts-expect-error
test[1].forEach((test) => {
//@ts-expect-error
const actual = resolve.apply(null, test[0]);
let actualAlt;
const os = resolve === path.win32.resolve ? 'win32' : 'posix';
if (resolve === path.win32.resolve && !isWindows) {
actualAlt = actual.replace(backslashRE, '/');
}
else if (resolve !== path.win32.resolve && isWindows) {
actualAlt = actual.replace(slashRE, '\\');
}
const expected = test[1];
const message =
`path.${os}.resolve(${test[0].map(JSON.stringify).join(',')})\n expect=${JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`;
if (actual !== expected && actualAlt !== expected) {
failures.push(`\n${message}`);
}
});
});
assert.strictEqual(failures.length, 0, failures.join(''));
// if (isWindows) {
// // Test resolving the current Windows drive letter from a spawned process.
// // See https://github.com/nodejs/node/issues/7215
// const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 2);
// const resolveFixture = fixtures.path('path-resolve.js');
// const spawnResult = child.spawnSync(
// process.argv[0], [resolveFixture, currentDriveLetter]);
// const resolvedPath = spawnResult.stdout.toString().trim();
// assert.strictEqual(resolvedPath.toLowerCase(), process.cwd().toLowerCase());
// }
});
test('basename', () => {
assert.strictEqual(path.basename(__filename), 'path.test.js');
assert.strictEqual(path.basename(__filename, '.js'), 'path.test');
assert.strictEqual(path.basename('.js', '.js'), '');
assert.strictEqual(path.basename(''), '');
assert.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext');
assert.strictEqual(path.basename('/basename.ext'), 'basename.ext');
assert.strictEqual(path.basename('basename.ext'), 'basename.ext');
assert.strictEqual(path.basename('basename.ext/'), 'basename.ext');
assert.strictEqual(path.basename('basename.ext//'), 'basename.ext');
assert.strictEqual(path.basename('aaa/bbb', '/bbb'), 'bbb');
assert.strictEqual(path.basename('aaa/bbb', 'a/bbb'), 'bbb');
assert.strictEqual(path.basename('aaa/bbb', 'bbb'), 'bbb');
assert.strictEqual(path.basename('aaa/bbb//', 'bbb'), 'bbb');
assert.strictEqual(path.basename('aaa/bbb', 'bb'), 'b');
assert.strictEqual(path.basename('aaa/bbb', 'b'), 'bb');
assert.strictEqual(path.basename('/aaa/bbb', '/bbb'), 'bbb');
assert.strictEqual(path.basename('/aaa/bbb', 'a/bbb'), 'bbb');
assert.strictEqual(path.basename('/aaa/bbb', 'bbb'), 'bbb');
assert.strictEqual(path.basename('/aaa/bbb//', 'bbb'), 'bbb');
assert.strictEqual(path.basename('/aaa/bbb', 'bb'), 'b');
assert.strictEqual(path.basename('/aaa/bbb', 'b'), 'bb');
assert.strictEqual(path.basename('/aaa/bbb'), 'bbb');
assert.strictEqual(path.basename('/aaa/'), 'aaa');
assert.strictEqual(path.basename('/aaa/b'), 'b');
assert.strictEqual(path.basename('/a/b'), 'b');
assert.strictEqual(path.basename('//a'), 'a');
assert.strictEqual(path.basename('a', 'a'), '');
// On Windows a backslash acts as a path separator.
assert.strictEqual(path.win32.basename('\\dir\\basename.ext'), 'basename.ext');
assert.strictEqual(path.win32.basename('\\basename.ext'), 'basename.ext');
assert.strictEqual(path.win32.basename('basename.ext'), 'basename.ext');
assert.strictEqual(path.win32.basename('basename.ext\\'), 'basename.ext');
assert.strictEqual(path.win32.basename('basename.ext\\\\'), 'basename.ext');
assert.strictEqual(path.win32.basename('foo'), 'foo');
assert.strictEqual(path.win32.basename('aaa\\bbb', '\\bbb'), 'bbb');
assert.strictEqual(path.win32.basename('aaa\\bbb', 'a\\bbb'), 'bbb');
assert.strictEqual(path.win32.basename('aaa\\bbb', 'bbb'), 'bbb');
assert.strictEqual(path.win32.basename('aaa\\bbb\\\\\\\\', 'bbb'), 'bbb');
assert.strictEqual(path.win32.basename('aaa\\bbb', 'bb'), 'b');
assert.strictEqual(path.win32.basename('aaa\\bbb', 'b'), 'bb');
assert.strictEqual(path.win32.basename('C:'), '');
assert.strictEqual(path.win32.basename('C:.'), '.');
assert.strictEqual(path.win32.basename('C:\\'), '');
assert.strictEqual(path.win32.basename('C:\\dir\\base.ext'), 'base.ext');
assert.strictEqual(path.win32.basename('C:\\basename.ext'), 'basename.ext');
assert.strictEqual(path.win32.basename('C:basename.ext'), 'basename.ext');
assert.strictEqual(path.win32.basename('C:basename.ext\\'), 'basename.ext');
assert.strictEqual(path.win32.basename('C:basename.ext\\\\'), 'basename.ext');
assert.strictEqual(path.win32.basename('C:foo'), 'foo');
assert.strictEqual(path.win32.basename('file:stream'), 'file:stream');
assert.strictEqual(path.win32.basename('a', 'a'), '');
// On unix a backslash is just treated as any other character.
assert.strictEqual(path.posix.basename('\\dir\\basename.ext'),
'\\dir\\basename.ext');
assert.strictEqual(path.posix.basename('\\basename.ext'), '\\basename.ext');
assert.strictEqual(path.posix.basename('basename.ext'), 'basename.ext');
assert.strictEqual(path.posix.basename('basename.ext\\'), 'basename.ext\\');
assert.strictEqual(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\');
assert.strictEqual(path.posix.basename('foo'), 'foo');
// POSIX filenames may include control characters
// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
const controlCharFilename = `Icon${String.fromCharCode(13)}`;
assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`),
controlCharFilename);
// Tests from VSCode
assert.equal(path.basename('foo/bar'), 'bar');
assert.equal(path.posix.basename('foo\\bar'), 'foo\\bar');
assert.equal(path.win32.basename('foo\\bar'), 'bar');
assert.equal(path.basename('/foo/bar'), 'bar');
assert.equal(path.posix.basename('\\foo\\bar'), '\\foo\\bar');
assert.equal(path.win32.basename('\\foo\\bar'), 'bar');
assert.equal(path.basename('./bar'), 'bar');
assert.equal(path.posix.basename('.\\bar'), '.\\bar');
assert.equal(path.win32.basename('.\\bar'), 'bar');
assert.equal(path.basename('/bar'), 'bar');
assert.equal(path.posix.basename('\\bar'), '\\bar');
assert.equal(path.win32.basename('\\bar'), 'bar');
assert.equal(path.basename('bar/'), 'bar');
assert.equal(path.posix.basename('bar\\'), 'bar\\');
assert.equal(path.win32.basename('bar\\'), 'bar');
assert.equal(path.basename('bar'), 'bar');
assert.equal(path.basename('////////'), '');
assert.equal(path.posix.basename('\\\\\\\\'), '\\\\\\\\');
assert.equal(path.win32.basename('\\\\\\\\'), '');
});
test('relative', () => {
const failures = [] as string[];
const relativeTests = [
[path.win32.relative,
// arguments result
[['c:/blah\\blah', 'd:/games', 'd:\\games'],
['c:/aaaa/bbbb', 'c:/aaaa', '..'],
['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'],
['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''],
['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'],
['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'],
['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'],
['c:/aaaa/bbbb', 'd:\\', 'd:\\'],
['c:/AaAa/bbbb', 'c:/aaaa/bbbb', ''],
['c:/aaaaa/', 'c:/aaaa/cccc', '..\\aaaa\\cccc'],
['C:\\foo\\bar\\baz\\quux', 'C:\\', '..\\..\\..\\..'],
['C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json', 'bar\\package.json'],
['C:\\foo\\bar\\baz-quux', 'C:\\foo\\bar\\baz', '..\\baz'],
['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz-quux', '..\\baz-quux'],
['\\\\foo\\bar', '\\\\foo\\bar\\baz', 'baz'],
['\\\\foo\\bar\\baz', '\\\\foo\\bar', '..'],
['\\\\foo\\bar\\baz-quux', '\\\\foo\\bar\\baz', '..\\baz'],
['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'],
['C:\\baz-quux', 'C:\\baz', '..\\baz'],
['C:\\baz', 'C:\\baz-quux', '..\\baz-quux'],
['\\\\foo\\baz-quux', '\\\\foo\\baz', '..\\baz'],
['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'],
['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'],
['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz']
]
],
[path.posix.relative,
// arguments result
[['/var/lib', '/var', '..'],
['/var/lib', '/bin', '../../bin'],
['/var/lib', '/var/lib', ''],
['/var/lib', '/var/apache', '../apache'],
['/var/', '/var/lib', 'lib'],
['/', '/var/lib', 'var/lib'],
['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'],
['/Users/a/web/b/test/mails', '/Users/a/web/b', '../..'],
['/foo/bar/baz-quux', '/foo/bar/baz', '../baz'],
['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'],
['/baz-quux', '/baz', '../baz'],
['/baz', '/baz-quux', '../baz-quux']
]
]
];
relativeTests.forEach((test) => {
const relative = test[0];
//@ts-expect-error
test[1].forEach((test) => {
//@ts-expect-error
const actual = relative(test[0], test[1]);
const expected = test[2];
const os = relative === path.win32.relative ? 'win32' : 'posix';
const message = `path.${os}.relative(${test.slice(0, 2).map(JSON.stringify).join(',')})\n expect=${JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`;
if (actual !== expected) {
failures.push(`\n${message}`);
}
});
});
assert.strictEqual(failures.length, 0, failures.join(''));
});
test('normalize', () => {
assert.strictEqual(path.win32.normalize('./fixtures///b/../b/c.js'),
'fixtures\\b\\c.js');
assert.strictEqual(path.win32.normalize('/foo/../../../bar'), '\\bar');
assert.strictEqual(path.win32.normalize('a//b//../b'), 'a\\b');
assert.strictEqual(path.win32.normalize('a//b//./c'), 'a\\b\\c');
assert.strictEqual(path.win32.normalize('a//b//.'), 'a\\b');
assert.strictEqual(path.win32.normalize('//server/share/dir/file.ext'),
'\\\\server\\share\\dir\\file.ext');
assert.strictEqual(path.win32.normalize('/a/b/c/../../../x/y/z'), '\\x\\y\\z');
assert.strictEqual(path.win32.normalize('C:'), 'C:.');
assert.strictEqual(path.win32.normalize('C:..\\abc'), 'C:..\\abc');
assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'),
'C:..\\..\\def');
assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\');
assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream');
assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\');
assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar');
assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz');
assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\');
assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..');
assert.strictEqual(path.win32.normalize('..\\foo..\\..\\..\\bar'),
'..\\..\\bar');
assert.strictEqual(path.win32.normalize('..\\...\\..\\.\\...\\..\\..\\bar'),
'..\\..\\bar');
assert.strictEqual(path.win32.normalize('../../../foo/../../../bar'),
'..\\..\\..\\..\\..\\bar');
assert.strictEqual(path.win32.normalize('../../../foo/../../../bar/../../'),
'..\\..\\..\\..\\..\\..\\');
assert.strictEqual(
path.win32.normalize('../foobar/barfoo/foo/../../../bar/../../'),
'..\\..\\'
);
assert.strictEqual(
path.win32.normalize('../.../../foobar/../../../bar/../../baz'),
'..\\..\\..\\..\\baz'
);
assert.strictEqual(path.win32.normalize('foo/bar\\baz'), 'foo\\bar\\baz');
assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'),
'fixtures/b/c.js');
assert.strictEqual(path.posix.normalize('/foo/../../../bar'), '/bar');
assert.strictEqual(path.posix.normalize('a//b//../b'), 'a/b');
assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c');
assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b');
assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z');
assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar');
assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/');
assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar');
assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz');
assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../');
assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..');
assert.strictEqual(path.posix.normalize('../foo../../../bar'), '../../bar');
assert.strictEqual(path.posix.normalize('../.../.././.../../../bar'),
'../../bar');
assert.strictEqual(path.posix.normalize('../../../foo/../../../bar'),
'../../../../../bar');
assert.strictEqual(path.posix.normalize('../../../foo/../../../bar/../../'),
'../../../../../../');
assert.strictEqual(
path.posix.normalize('../foobar/barfoo/foo/../../../bar/../../'),
'../../'
);
assert.strictEqual(
path.posix.normalize('../.../../foobar/../../../bar/../../baz'),
'../../../../baz'
);
assert.strictEqual(path.posix.normalize('foo/bar\\baz'), 'foo/bar\\baz');
});
test('isAbsolute', () => {
assert.strictEqual(path.win32.isAbsolute('/'), true);
assert.strictEqual(path.win32.isAbsolute('//'), true);
assert.strictEqual(path.win32.isAbsolute('//server'), true);
assert.strictEqual(path.win32.isAbsolute('//server/file'), true);
assert.strictEqual(path.win32.isAbsolute('\\\\server\\file'), true);
assert.strictEqual(path.win32.isAbsolute('\\\\server'), true);
assert.strictEqual(path.win32.isAbsolute('\\\\'), true);
assert.strictEqual(path.win32.isAbsolute('c'), false);
assert.strictEqual(path.win32.isAbsolute('c:'), false);
assert.strictEqual(path.win32.isAbsolute('c:\\'), true);
assert.strictEqual(path.win32.isAbsolute('c:/'), true);
assert.strictEqual(path.win32.isAbsolute('c://'), true);
assert.strictEqual(path.win32.isAbsolute('C:/Users/'), true);
assert.strictEqual(path.win32.isAbsolute('C:\\Users\\'), true);
assert.strictEqual(path.win32.isAbsolute('C:cwd/another'), false);
assert.strictEqual(path.win32.isAbsolute('C:cwd\\another'), false);
assert.strictEqual(path.win32.isAbsolute('directory/directory'), false);
assert.strictEqual(path.win32.isAbsolute('directory\\directory'), false);
assert.strictEqual(path.posix.isAbsolute('/home/foo'), true);
assert.strictEqual(path.posix.isAbsolute('/home/foo/..'), true);
assert.strictEqual(path.posix.isAbsolute('bar/'), false);
assert.strictEqual(path.posix.isAbsolute('./baz'), false);
// Tests from VSCode:
// Absolute Paths
[
'C:/',
'C:\\',
'C:/foo',
'C:\\foo',
'z:/foo/bar.txt',
'z:\\foo\\bar.txt',
'\\\\localhost\\c$\\foo',
'/',
'/foo'
].forEach(absolutePath => {
assert.ok(path.win32.isAbsolute(absolutePath), absolutePath);
});
[
'/',
'/foo',
'/foo/bar.txt'
].forEach(absolutePath => {
assert.ok(path.posix.isAbsolute(absolutePath), absolutePath);
});
// Relative Paths
[
'',
'foo',
'foo/bar',
'./foo',
'http://foo.com/bar'
].forEach(nonAbsolutePath => {
assert.ok(!path.win32.isAbsolute(nonAbsolutePath), nonAbsolutePath);
});
[
'',
'foo',
'foo/bar',
'./foo',
'http://foo.com/bar',
'z:/foo/bar.txt',
].forEach(nonAbsolutePath => {
assert.ok(!path.posix.isAbsolute(nonAbsolutePath), nonAbsolutePath);
});
});
test('path', () => {
// path.sep tests
// windows
assert.strictEqual(path.win32.sep, '\\');
// posix
assert.strictEqual(path.posix.sep, '/');
// path.delimiter tests
// windows
assert.strictEqual(path.win32.delimiter, ';');
// posix
assert.strictEqual(path.posix.delimiter, ':');
// if (isWindows) {
// assert.strictEqual(path, path.win32);
// } else {
// assert.strictEqual(path, path.posix);
// }
});
// test('perf', () => {
// const folderNames = [
// 'abc',
// 'Users',
// 'reallylongfoldername',
// 's',
// 'reallyreallyreallylongfoldername',
// 'home'
// ];
// const basePaths = [
// 'C:',
// '',
// ];
// const separators = [
// '\\',
// '/'
// ];
// function randomInt(ciel: number): number {
// return Math.floor(Math.random() * ciel);
// }
// let pathsToNormalize = [];
// let pathsToJoin = [];
// let i;
// for (i = 0; i < 1000000; i++) {
// const basePath = basePaths[randomInt(basePaths.length)];
// let lengthOfPath = randomInt(10) + 2;
// let pathToNormalize = basePath + separators[randomInt(separators.length)];
// while (lengthOfPath-- > 0) {
// pathToNormalize = pathToNormalize + folderNames[randomInt(folderNames.length)] + separators[randomInt(separators.length)];
// }
// pathsToNormalize.push(pathToNormalize);
// let pathToJoin = '';
// lengthOfPath = randomInt(10) + 2;
// while (lengthOfPath-- > 0) {
// pathToJoin = pathToJoin + folderNames[randomInt(folderNames.length)] + separators[randomInt(separators.length)];
// }
// pathsToJoin.push(pathToJoin + '.ts');
// }
// let newTime = 0;
// let j;
// for(j = 0; j < pathsToJoin.length; j++) {
// const path1 = pathsToNormalize[j];
// const path2 = pathsToNormalize[j];
// const newStart = performance.now();
// path.join(path1, path2);
// newTime += performance.now() - newStart;
// }
// assert.ok(false, `Time: ${newTime}ms.`);
// });
});

View File

@@ -4,388 +4,306 @@
*--------------------------------------------------------------------------------------------*/
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 { tmpdir } from 'os';
import { join, sep } from 'vs/base/common/path';
import { generateUuid } from 'vs/base/common/uuid';
import { copy, exists, mkdirp, move, readdir, readDirsInDir, readdirWithFileTypes, readFile, renameIgnoreError, rimraf, RimRafMode, rimrafSync, statLink, writeFile, writeFileSync } from 'vs/base/node/pfs';
import { timeout } from 'vs/base/common/async';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { isWindows } from 'vs/base/common/platform';
import { canNormalize } from 'vs/base/common/normalization';
import { VSBuffer } from 'vs/base/common/buffer';
import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils';
suite('PFS', function () {
flakySuite('PFS', function () {
// Given issues such as https://github.com/microsoft/vscode/issues/84066
// we see random test failures when accessing the native file system. To
// diagnose further, we retry node.js file access tests up to 3 times to
// rule out any random disk issue.
this.retries(3);
let testDir: string;
setup(() => {
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'pfs');
return mkdirp(testDir, 493);
});
teardown(() => {
return rimraf(testDir);
});
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');
const testFile = join(testDir, 'writefile.txt');
await pfs.mkdirp(newDir, 493);
assert.ok(fs.existsSync(newDir));
assert.ok(!(await exists(testFile)));
await pfs.writeFile(testFile, 'Hello World', (null!));
assert.equal(fs.readFileSync(testFile), 'Hello World');
await writeFile(testFile, 'Hello World', (null!));
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
assert.strictEqual((await readFile(testFile)).toString(), 'Hello World');
});
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));
const testFile1 = join(testDir, 'writefile1.txt');
const testFile2 = join(testDir, 'writefile2.txt');
const testFile3 = join(testDir, 'writefile3.txt');
const testFile4 = join(testDir, 'writefile4.txt');
const testFile5 = join(testDir, 'writefile5.txt');
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!))
writeFile(testFile1, 'Hello World 1', (null!)),
writeFile(testFile2, 'Hello World 2', (null!)),
writeFile(testFile3, 'Hello World 3', (null!)),
writeFile(testFile4, 'Hello World 4', (null!)),
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);
assert.strictEqual(fs.readFileSync(testFile1).toString(), 'Hello World 1');
assert.strictEqual(fs.readFileSync(testFile2).toString(), 'Hello World 2');
assert.strictEqual(fs.readFileSync(testFile3).toString(), 'Hello World 3');
assert.strictEqual(fs.readFileSync(testFile4).toString(), 'Hello World 4');
assert.strictEqual(fs.readFileSync(testFile5).toString(), 'Hello World 5');
});
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));
const testFile = join(testDir, 'writefile.txt');
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))
writeFile(testFile, 'Hello World 1', undefined),
writeFile(testFile, 'Hello World 2', undefined),
timeout(10).then(() => writeFile(testFile, 'Hello World 3', undefined)),
writeFile(testFile, 'Hello World 4', undefined),
timeout(10).then(() => writeFile(testFile, 'Hello World 5', undefined))
]);
assert.equal(fs.readFileSync(testFile), 'Hello World 5');
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
assert.strictEqual(fs.readFileSync(testFile).toString(), 'Hello World 5');
});
test('rimraf - simple - unlink', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
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));
await rimraf(testDir);
assert.ok(!fs.existsSync(testDir));
});
test('rimraf - simple - move', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
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));
await rimraf(testDir, RimRafMode.MOVE);
assert.ok(!fs.existsSync(testDir));
});
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);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(join(testDir, 'somefolder'));
fs.writeFileSync(join(testDir, 'somefolder', 'somefile.txt'), 'Contents');
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));
await rimraf(testDir);
assert.ok(!fs.existsSync(testDir));
});
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);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(join(testDir, 'somefolder'));
fs.writeFileSync(join(testDir, 'somefolder', 'somefile.txt'), 'Contents');
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));
await rimraf(testDir, RimRafMode.MOVE);
assert.ok(!fs.existsSync(testDir));
});
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);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
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));
await rimraf(testDir, RimRafMode.MOVE);
assert.ok(!fs.existsSync(testDir));
});
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);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
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));
await rimraf(`${testDir}${sep}`, RimRafMode.MOVE);
assert.ok(!fs.existsSync(testDir));
});
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);
const nonExistingDir = join(testDir, 'not-existing');
rimrafSync(nonExistingDir);
pfs.rimrafSync(newDir);
assert.ok(!fs.existsSync(newDir));
assert.ok(!fs.existsSync(nonExistingDir));
});
test('rimrafSync - simple', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
await pfs.mkdirp(newDir, 493);
rimrafSync(testDir);
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
pfs.rimrafSync(newDir);
assert.ok(!fs.existsSync(newDir));
assert.ok(!fs.existsSync(testDir));
});
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);
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
await pfs.mkdirp(newDir, 493);
fs.writeFileSync(path.join(newDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(path.join(newDir, 'someOtherFile.txt'), 'Contents');
fs.mkdirSync(join(testDir, 'somefolder'));
fs.writeFileSync(join(testDir, 'somefolder', 'somefile.txt'), 'Contents');
fs.mkdirSync(path.join(newDir, 'somefolder'));
fs.writeFileSync(path.join(newDir, 'somefolder', 'somefile.txt'), 'Contents');
rimrafSync(testDir);
pfs.rimrafSync(newDir);
assert.ok(!fs.existsSync(newDir));
assert.ok(!fs.existsSync(testDir));
});
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);
}
test('moveIgnoreError', () => {
return renameIgnoreError(join(testDir, 'foo'), join(testDir, 'bar'));
});
test('copy, move and delete', async () => {
const id = uuid.generateUuid();
const id2 = uuid.generateUuid();
const id = generateUuid();
const id2 = 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);
const parentDir = join(tmpdir(), 'vsctests', 'pfs');
const targetDir = join(parentDir, id);
const targetDir2 = join(parentDir, id2);
await pfs.copy(sourceDir, targetDir);
await 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')));
assert.ok(fs.existsSync(join(targetDir, 'index.html')));
assert.ok(fs.existsSync(join(targetDir, 'site.css')));
assert.ok(fs.existsSync(join(targetDir, 'examples')));
assert.ok(fs.statSync(join(targetDir, 'examples')).isDirectory());
assert.ok(fs.existsSync(join(targetDir, 'examples', 'small.jxs')));
await pfs.move(targetDir, targetDir2);
await 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')));
assert.ok(fs.existsSync(join(targetDir2, 'index.html')));
assert.ok(fs.existsSync(join(targetDir2, 'site.css')));
assert.ok(fs.existsSync(join(targetDir2, 'examples')));
assert.ok(fs.statSync(join(targetDir2, 'examples')).isDirectory());
assert.ok(fs.existsSync(join(targetDir2, 'examples', 'small.jxs')));
await pfs.move(path.join(targetDir2, 'index.html'), path.join(targetDir2, 'index_moved.html'));
await move(join(targetDir2, 'index.html'), join(targetDir2, 'index_moved.html'));
assert.ok(!fs.existsSync(path.join(targetDir2, 'index.html')));
assert.ok(fs.existsSync(path.join(targetDir2, 'index_moved.html')));
assert.ok(!fs.existsSync(join(targetDir2, 'index.html')));
assert.ok(fs.existsSync(join(targetDir2, 'index_moved.html')));
await pfs.rimraf(parentDir, pfs.RimRafMode.MOVE);
await rimraf(parentDir);
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);
test('copy skips over dangling symbolic links', async () => {
const id1 = generateUuid();
const symbolicLinkTarget = join(testDir, id1);
await pfs.mkdirp(newDir, 493);
const id2 = generateUuid();
const symbolicLink = join(testDir, id2);
const id3 = generateUuid();
const copyTarget = join(testDir, id3);
await mkdirp(symbolicLinkTarget, 493);
fs.symlinkSync(symbolicLinkTarget, symbolicLink, 'junction');
await rimraf(symbolicLinkTarget);
await copy(symbolicLink, copyTarget); // this should not throw
assert.ok(!fs.existsSync(copyTarget));
});
test('mkdirp', async () => {
const newDir = join(testDir, generateUuid());
await mkdirp(newDir, 493);
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);
fs.mkdirSync(join(testDir, 'somefolder1'));
fs.mkdirSync(join(testDir, 'somefolder2'));
fs.mkdirSync(join(testDir, 'somefolder3'));
fs.writeFileSync(join(testDir, 'somefile.txt'), 'Contents');
fs.writeFileSync(join(testDir, 'someOtherFile.txt'), 'Contents');
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);
const result = await readDirsInDir(testDir);
assert.strictEqual(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; // Symlinks are not the same on win, and we can not create them programitically without admin privileges
}
const id1 = generateUuid();
const directory = join(testDir, id1);
const id1 = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id1);
const directory = path.join(parentDir, 'pfs', id1);
const id2 = generateUuid();
const symbolicLink = join(testDir, id2);
const id2 = uuid.generateUuid();
const symbolicLink = path.join(parentDir, 'pfs', id2);
await mkdirp(directory, 493);
await pfs.mkdirp(directory, 493);
fs.symlinkSync(directory, symbolicLink, 'junction');
fs.symlinkSync(directory, symbolicLink);
let statAndIsLink = await pfs.statLink(directory);
let statAndIsLink = await statLink(directory);
assert.ok(!statAndIsLink?.symbolicLink);
statAndIsLink = await pfs.statLink(symbolicLink);
statAndIsLink = await statLink(symbolicLink);
assert.ok(statAndIsLink?.symbolicLink);
assert.ok(!statAndIsLink?.symbolicLink?.dangling);
pfs.rimrafSync(directory);
});
test('stat link (non existing target)', async () => {
if (isWindows) {
return; // Symlinks are not the same on win, and we can not create them programitically without admin privileges
}
const id1 = generateUuid();
const directory = join(testDir, id1);
const id1 = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id1);
const directory = path.join(parentDir, 'pfs', id1);
const id2 = generateUuid();
const symbolicLink = join(testDir, id2);
const id2 = uuid.generateUuid();
const symbolicLink = path.join(parentDir, 'pfs', id2);
await mkdirp(directory, 493);
await pfs.mkdirp(directory, 493);
fs.symlinkSync(directory, symbolicLink, 'junction');
fs.symlinkSync(directory, symbolicLink);
await rimraf(directory);
pfs.rimrafSync(directory);
const statAndIsLink = await pfs.statLink(symbolicLink);
const statAndIsLink = await statLink(symbolicLink);
assert.ok(statAndIsLink?.symbolicLink);
assert.ok(statAndIsLink?.symbolicLink?.dangling);
});
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, 'öäü');
const id = generateUuid();
const newDir = join(testDir, 'pfs', id, 'öäü');
await pfs.mkdirp(newDir, 493);
await 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);
const children = await readdir(join(testDir, 'pfs', id));
assert.strictEqual(children.some(n => n === 'öäü'), true); // Mac always converts to NFD, so
}
});
test('readdirWithFileTypes', async () => {
if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const testDir = path.join(parentDir, 'pfs', id);
const newDir = join(testDir, 'öäü');
await mkdirp(newDir, 493);
const newDir = path.join(testDir, 'öäü');
await pfs.mkdirp(newDir, 493);
await pfs.writeFile(path.join(testDir, 'somefile.txt'), 'contents');
await writeFile(join(testDir, 'somefile.txt'), 'contents');
assert.ok(fs.existsSync(newDir));
const children = await pfs.readdirWithFileTypes(testDir);
const children = await readdirWithFileTypes(testDir);
assert.equal(children.some(n => n.name === 'öäü'), true); // Mac always converts to NFD, so
assert.equal(children.some(n => n.isDirectory()), true);
assert.strictEqual(children.some(n => n.name === 'öäü'), true); // Mac always converts to NFD, so
assert.strictEqual(children.some(n => n.isDirectory()), true);
assert.equal(children.some(n => n.name === 'somefile.txt'), true);
assert.equal(children.some(n => n.isFile()), true);
await pfs.rimraf(parentDir);
assert.strictEqual(children.some(n => n.name === 'somefile.txt'), true);
assert.strictEqual(children.some(n => n.isFile()), true);
}
});
@@ -416,65 +334,41 @@ suite('PFS', function () {
bigData: string | Buffer | 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');
const testFile = join(testDir, 'flushed.txt');
await pfs.mkdirp(newDir, 493);
assert.ok(fs.existsSync(newDir));
assert.ok(fs.existsSync(testDir));
await pfs.writeFile(testFile, smallData);
assert.equal(fs.readFileSync(testFile), smallDataValue);
await writeFile(testFile, smallData);
assert.strictEqual(fs.readFileSync(testFile).toString(), smallDataValue);
await pfs.writeFile(testFile, bigData);
assert.equal(fs.readFileSync(testFile), bigDataValue);
await pfs.rimraf(parentDir);
await writeFile(testFile, bigData);
assert.strictEqual(fs.readFileSync(testFile).toString(), bigDataValue);
}
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');
const testFile = join(testDir, '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!
fs.mkdirSync(testFile); // this will trigger an error later because testFile is now a directory!
let expectedError: Error | undefined;
try {
await pfs.writeFile(testFile, 'Hello World');
await writeFile(testFile, 'Hello World');
} catch (error) {
expectedError = error;
}
assert.ok(expectedError);
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');
const testFile = join(testDir, 'flushed.txt');
await pfs.mkdirp(newDir, 493);
assert.ok(fs.existsSync(newDir));
pfs.writeFileSync(testFile, 'Hello World');
assert.equal(fs.readFileSync(testFile), 'Hello World');
writeFileSync(testFile, 'Hello World');
assert.strictEqual(fs.readFileSync(testFile).toString(), '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);
writeFileSync(testFile, largeString);
assert.strictEqual(fs.readFileSync(testFile).toString(), largeString);
});
});

View File

@@ -6,14 +6,10 @@
import * as assert from 'assert';
import * as net from 'net';
import * as ports from 'vs/base/node/ports';
import { flakySuite } from 'vs/base/test/node/testUtils';
suite('Ports', () => {
test('Finds a free port (no timeout)', function (done) {
this.timeout(1000 * 10); // higher timeout for this test
if (process.env['VSCODE_PID']) {
return done(); // this test fails when run from within VS Code
}
flakySuite('Ports', () => {
(process.env['VSCODE_PID'] ? test.skip /* this test fails when run from within VS Code */ : test)('Finds a free port (no timeout)', function (done) {
// get an initial freeport >= 7000
ports.findFreePort(7000, 100, 300000).then(initialPort => {

View File

@@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------------------
* 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 fs from 'fs';
import * as os from 'os';
import * as platform from 'vs/base/common/platform';
import { enumeratePowerShellInstallations, getFirstAvailablePowerShellInstallation, IPowerShellExeDetails } from 'vs/base/node/powershell';
function checkPath(exePath: string) {
// Check to see if the path exists
let pathCheckResult = false;
try {
const stat = fs.statSync(exePath);
pathCheckResult = stat.isFile();
} catch {
// fs.exists throws on Windows with SymbolicLinks so we
// also use lstat to try and see if the file exists.
try {
pathCheckResult = fs.statSync(fs.readlinkSync(exePath)).isFile();
} catch {
}
}
assert.strictEqual(pathCheckResult, true);
}
if (platform.isWindows) {
suite('PowerShell finder', () => {
test('Can find first available PowerShell', async () => {
const pwshExe = await getFirstAvailablePowerShellInstallation();
const exePath = pwshExe?.exePath;
assert.notStrictEqual(exePath, null);
assert.notStrictEqual(pwshExe?.displayName, null);
checkPath(exePath!);
});
test('Can enumerate PowerShells', async () => {
const isOS64Bit = os.arch() === 'x64';
const pwshs = new Array<IPowerShellExeDetails>();
for await (const p of enumeratePowerShellInstallations()) {
pwshs.push(p);
}
const powershellLog = 'Found these PowerShells:\n' + pwshs.map(p => `${p.displayName}: ${p.exePath}`).join('\n');
assert.strictEqual(pwshs.length >= (isOS64Bit ? 2 : 1), true, powershellLog);
for (const pwsh of pwshs) {
checkPath(pwsh.exePath);
}
const lastIndex = pwshs.length - 1;
const secondToLastIndex = pwshs.length - 2;
// 64bit process on 64bit OS
if (process.arch === 'x64') {
checkPath(pwshs[secondToLastIndex].exePath);
assert.strictEqual(pwshs[secondToLastIndex].displayName, 'Windows PowerShell', powershellLog);
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
} else if (isOS64Bit) {
// 32bit process on 64bit OS
// Windows PowerShell x86 comes first if vscode is 32bit
checkPath(pwshs[secondToLastIndex].exePath);
assert.strictEqual(pwshs[secondToLastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell', powershellLog);
} else {
// 32bit or ARM process
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
}
});
});
}

View File

@@ -13,9 +13,9 @@ import { getPathFromAmdModule } from 'vs/base/common/amd';
function fork(id: string): cp.ChildProcess {
const opts: any = {
env: objects.mixin(objects.deepClone(process.env), {
AMD_ENTRYPOINT: id,
PIPE_LOGGING: 'true',
VERBOSE_LOGGING: true
VSCODE_AMD_ENTRYPOINT: id,
VSCODE_PIPE_LOGGING: 'true',
VSCODE_VERBOSE_LOGGING: true
})
};
@@ -59,11 +59,7 @@ suite('Processes', () => {
});
});
test('buffered sending - lots of data (potential deadlock on win32)', function (done: () => void) {
if (!platform.isWindows || process.env['VSCODE_PID']) {
return done(); // test is only relevant for Windows and seems to crash randomly on some Linux builds
}
(!platform.isWindows || process.env['VSCODE_PID'] ? test.skip : test)('buffered sending - lots of data (potential deadlock on win32)', function (done: () => void) { // test is only relevant for Windows and seems to crash randomly on some Linux builds
const child = fork('vs/base/test/node/processes/fixtures/fork_large');
const sender = processes.createQueuedSender(child);

View File

@@ -3,9 +3,25 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import type { Suite } from 'mocha';
import { join } from 'vs/base/common/path';
import { generateUuid } from 'vs/base/common/uuid';
export function getRandomTestPath(tmpdir: string, ...segments: string[]): string {
return join(tmpdir, ...segments, generateUuid());
}
export function flakySuite(title: string, fn: (this: Suite) => void): Suite {
return suite(title, function () {
// Flaky suites need retries and timeout to complete
// e.g. because they access the file system which can
// be unreliable depending on the environment.
this.retries(3);
this.timeout(1000 * 20);
// Invoke suite ensuring that `this` is
// properly wired in.
fn.call(this);
});
}

View File

@@ -5,24 +5,33 @@
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import * as os from 'os';
import { tmpdir } from 'os';
import { extract } from 'vs/base/node/zip';
import { generateUuid } from 'vs/base/common/uuid';
import { rimraf, exists } from 'vs/base/node/pfs';
import { rimraf, exists, mkdirp } from 'vs/base/node/pfs';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { createCancelablePromise } from 'vs/base/common/async';
const fixtures = getPathFromAmdModule(require, './fixtures');
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
suite('Zip', () => {
test('extract should handle directories', () => {
const fixture = path.join(fixtures, 'extract.zip');
const target = path.join(os.tmpdir(), generateUuid());
let testDir: string;
return createCancelablePromise(token => extract(fixture, target, {}, token)
.then(() => exists(path.join(target, 'extension')))
.then(exists => assert(exists))
.then(() => rimraf(target)));
setup(() => {
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'zip');
return mkdirp(testDir);
});
teardown(() => {
return rimraf(testDir);
});
test('extract should handle directories', async () => {
const fixtures = getPathFromAmdModule(require, './fixtures');
const fixture = path.join(fixtures, 'extract.zip');
await createCancelablePromise(token => extract(fixture, testDir, {}, token));
const doesExist = await exists(path.join(testDir, 'extension'));
assert(doesExist);
});
});