path: allow calling platform specific methods
Add path.posix and path.win32 which have the specific methods like resolve and normalize so you can specifically normalize or resolve based on the target platform. PR-URL: https://github.com/joyent/node/pull/5661 Reviewed-by: Chris Dickinson <christopher.s.dickinson@gmail.com>
This commit is contained in:
parent
4dc8b26bbe
commit
6a90a06002
@ -201,3 +201,13 @@ An example on Windows:
|
|||||||
process.env.PATH.split(path.delimiter)
|
process.env.PATH.split(path.delimiter)
|
||||||
// returns
|
// returns
|
||||||
['C:\Windows\system32', 'C:\Windows', 'C:\Program Files\nodejs\']
|
['C:\Windows\system32', 'C:\Windows', 'C:\Program Files\nodejs\']
|
||||||
|
|
||||||
|
## path.posix
|
||||||
|
|
||||||
|
Provide access to aforementioned `path` methods but always interact in a posix
|
||||||
|
compatible way.
|
||||||
|
|
||||||
|
## path.win32
|
||||||
|
|
||||||
|
Provide access to aforementioned `path` methods but always interact in a win32
|
||||||
|
compatible way.
|
||||||
|
815
lib/path.js
815
lib/path.js
@ -55,401 +55,283 @@ function normalizeArray(parts, allowAboveRoot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isWindows) {
|
// Regex to split a windows path into three parts: [*, device, slash,
|
||||||
// Regex to split a windows path into three parts: [*, device, slash,
|
// tail] windows-only
|
||||||
// tail] windows-only
|
var splitDeviceRe =
|
||||||
var splitDeviceRe =
|
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
||||||
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
|
||||||
|
|
||||||
// Regex to split the tail part of the above into [*, dir, basename, ext]
|
// Regex to split the tail part of the above into [*, dir, basename, ext]
|
||||||
var splitTailRe =
|
var splitTailRe =
|
||||||
/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
|
/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
|
||||||
|
|
||||||
// Function to split a filename into [root, dir, basename, ext]
|
var win32 = {};
|
||||||
// windows version
|
|
||||||
var splitPath = function(filename) {
|
|
||||||
// Separate device+slash from tail
|
|
||||||
var result = splitDeviceRe.exec(filename),
|
|
||||||
device = (result[1] || '') + (result[2] || ''),
|
|
||||||
tail = result[3] || '';
|
|
||||||
// Split the tail into dir, basename and extension
|
|
||||||
var result2 = splitTailRe.exec(tail),
|
|
||||||
dir = result2[1],
|
|
||||||
basename = result2[2],
|
|
||||||
ext = result2[3];
|
|
||||||
return [device, dir, basename, ext];
|
|
||||||
};
|
|
||||||
|
|
||||||
var normalizeUNCRoot = function(device) {
|
// Function to split a filename into [root, dir, basename, ext]
|
||||||
return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
|
win32.splitPath = function(filename) {
|
||||||
};
|
// Separate device+slash from tail
|
||||||
|
var result = splitDeviceRe.exec(filename),
|
||||||
|
device = (result[1] || '') + (result[2] || ''),
|
||||||
|
tail = result[3] || '';
|
||||||
|
// Split the tail into dir, basename and extension
|
||||||
|
var result2 = splitTailRe.exec(tail),
|
||||||
|
dir = result2[1],
|
||||||
|
basename = result2[2],
|
||||||
|
ext = result2[3];
|
||||||
|
return [device, dir, basename, ext];
|
||||||
|
};
|
||||||
|
|
||||||
// path.resolve([from ...], to)
|
var normalizeUNCRoot = function(device) {
|
||||||
// windows version
|
return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
|
||||||
exports.resolve = function() {
|
};
|
||||||
var resolvedDevice = '',
|
|
||||||
resolvedTail = '',
|
|
||||||
resolvedAbsolute = false;
|
|
||||||
|
|
||||||
for (var i = arguments.length - 1; i >= -1; i--) {
|
// path.resolve([from ...], to)
|
||||||
var path;
|
win32.resolve = function() {
|
||||||
if (i >= 0) {
|
var resolvedDevice = '',
|
||||||
path = arguments[i];
|
resolvedTail = '',
|
||||||
} else if (!resolvedDevice) {
|
resolvedAbsolute = false;
|
||||||
path = process.cwd();
|
|
||||||
} else {
|
|
||||||
// Windows has the concept of drive-specific current working
|
|
||||||
// directories. If we've resolved a drive letter but not yet an
|
|
||||||
// absolute path, get cwd for that drive. We're sure the device is not
|
|
||||||
// an unc path at this points, because unc paths are always absolute.
|
|
||||||
path = process.env['=' + resolvedDevice];
|
|
||||||
// Verify that a drive-local cwd was found and that it actually points
|
|
||||||
// to our drive. If not, default to the drive's root.
|
|
||||||
if (!path || path.substr(0, 3).toLowerCase() !==
|
|
||||||
resolvedDevice.toLowerCase() + '\\') {
|
|
||||||
path = resolvedDevice + '\\';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip empty and invalid entries
|
for (var i = arguments.length - 1; i >= -1; i--) {
|
||||||
if (!util.isString(path)) {
|
var path;
|
||||||
throw new TypeError('Arguments to path.resolve must be strings');
|
if (i >= 0) {
|
||||||
} else if (!path) {
|
path = arguments[i];
|
||||||
continue;
|
} else if (!resolvedDevice) {
|
||||||
}
|
path = process.cwd();
|
||||||
|
} else {
|
||||||
var result = splitDeviceRe.exec(path),
|
// Windows has the concept of drive-specific current working
|
||||||
device = result[1] || '',
|
// directories. If we've resolved a drive letter but not yet an
|
||||||
isUnc = device && device.charAt(1) !== ':',
|
// absolute path, get cwd for that drive. We're sure the device is not
|
||||||
isAbsolute = exports.isAbsolute(path),
|
// an unc path at this points, because unc paths are always absolute.
|
||||||
tail = result[3];
|
path = process.env['=' + resolvedDevice];
|
||||||
|
// Verify that a drive-local cwd was found and that it actually points
|
||||||
if (device &&
|
// to our drive. If not, default to the drive's root.
|
||||||
resolvedDevice &&
|
if (!path || path.substr(0, 3).toLowerCase() !==
|
||||||
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
|
resolvedDevice.toLowerCase() + '\\') {
|
||||||
// This path points to another device so it is not applicable
|
path = resolvedDevice + '\\';
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolvedDevice) {
|
|
||||||
resolvedDevice = device;
|
|
||||||
}
|
|
||||||
if (!resolvedAbsolute) {
|
|
||||||
resolvedTail = tail + '\\' + resolvedTail;
|
|
||||||
resolvedAbsolute = isAbsolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolvedDevice && resolvedAbsolute) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert slashes to backslashes when `resolvedDevice` points to an UNC
|
// Skip empty and invalid entries
|
||||||
// root. Also squash multiple slashes into a single one where appropriate.
|
if (!util.isString(path)) {
|
||||||
if (isUnc) {
|
throw new TypeError('Arguments to path.resolve must be strings');
|
||||||
resolvedDevice = normalizeUNCRoot(resolvedDevice);
|
} else if (!path) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point the path should be resolved to a full absolute path,
|
|
||||||
// but handle relative paths to be safe (might happen when process.cwd()
|
|
||||||
// fails)
|
|
||||||
|
|
||||||
// Normalize the tail path
|
|
||||||
|
|
||||||
function f(p) {
|
|
||||||
return !!p;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
|
|
||||||
!resolvedAbsolute).join('\\');
|
|
||||||
|
|
||||||
// If device is a drive letter, we'll normalize to lower case.
|
|
||||||
if (resolvedDevice && resolvedDevice.charAt(1) === ':') {
|
|
||||||
resolvedDevice = resolvedDevice[0].toLowerCase() +
|
|
||||||
resolvedDevice.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
|
|
||||||
'.';
|
|
||||||
};
|
|
||||||
|
|
||||||
// windows version
|
|
||||||
exports.normalize = function(path) {
|
|
||||||
var result = splitDeviceRe.exec(path),
|
var result = splitDeviceRe.exec(path),
|
||||||
device = result[1] || '',
|
device = result[1] || '',
|
||||||
isUnc = device && device.charAt(1) !== ':',
|
isUnc = device && device.charAt(1) !== ':',
|
||||||
isAbsolute = exports.isAbsolute(path),
|
isAbsolute = win32.isAbsolute(path),
|
||||||
tail = result[3],
|
tail = result[3];
|
||||||
trailingSlash = /[\\\/]$/.test(tail);
|
|
||||||
|
|
||||||
// If device is a drive letter, we'll normalize to lower case.
|
if (device &&
|
||||||
if (device && device.charAt(1) === ':') {
|
resolvedDevice &&
|
||||||
device = device[0].toLowerCase() + device.substr(1);
|
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
|
||||||
|
// This path points to another device so it is not applicable
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize the tail path
|
if (!resolvedDevice) {
|
||||||
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
|
resolvedDevice = device;
|
||||||
return !!p;
|
|
||||||
}), !isAbsolute).join('\\');
|
|
||||||
|
|
||||||
if (!tail && !isAbsolute) {
|
|
||||||
tail = '.';
|
|
||||||
}
|
}
|
||||||
if (tail && trailingSlash) {
|
if (!resolvedAbsolute) {
|
||||||
tail += '\\';
|
resolvedTail = tail + '\\' + resolvedTail;
|
||||||
|
resolvedAbsolute = isAbsolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert slashes to backslashes when `device` points to an UNC root.
|
if (resolvedDevice && resolvedAbsolute) {
|
||||||
// Also squash multiple slashes into a single one where appropriate.
|
break;
|
||||||
if (isUnc) {
|
}
|
||||||
device = normalizeUNCRoot(device);
|
}
|
||||||
|
|
||||||
|
// Convert slashes to backslashes when `resolvedDevice` points to an UNC
|
||||||
|
// root. Also squash multiple slashes into a single one where appropriate.
|
||||||
|
if (isUnc) {
|
||||||
|
resolvedDevice = normalizeUNCRoot(resolvedDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point the path should be resolved to a full absolute path,
|
||||||
|
// but handle relative paths to be safe (might happen when process.cwd()
|
||||||
|
// fails)
|
||||||
|
|
||||||
|
// Normalize the tail path
|
||||||
|
|
||||||
|
function f(p) {
|
||||||
|
return !!p;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
|
||||||
|
!resolvedAbsolute).join('\\');
|
||||||
|
|
||||||
|
// If device is a drive letter, we'll normalize to lower case.
|
||||||
|
if (resolvedDevice && resolvedDevice.charAt(1) === ':') {
|
||||||
|
resolvedDevice = resolvedDevice[0].toLowerCase() +
|
||||||
|
resolvedDevice.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
|
||||||
|
'.';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
win32.normalize = function(path) {
|
||||||
|
var result = splitDeviceRe.exec(path),
|
||||||
|
device = result[1] || '',
|
||||||
|
isUnc = device && device.charAt(1) !== ':',
|
||||||
|
isAbsolute = win32.isAbsolute(path),
|
||||||
|
tail = result[3],
|
||||||
|
trailingSlash = /[\\\/]$/.test(tail);
|
||||||
|
|
||||||
|
// If device is a drive letter, we'll normalize to lower case.
|
||||||
|
if (device && device.charAt(1) === ':') {
|
||||||
|
device = device[0].toLowerCase() + device.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize the tail path
|
||||||
|
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
|
||||||
|
return !!p;
|
||||||
|
}), !isAbsolute).join('\\');
|
||||||
|
|
||||||
|
if (!tail && !isAbsolute) {
|
||||||
|
tail = '.';
|
||||||
|
}
|
||||||
|
if (tail && trailingSlash) {
|
||||||
|
tail += '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert slashes to backslashes when `device` points to an UNC root.
|
||||||
|
// Also squash multiple slashes into a single one where appropriate.
|
||||||
|
if (isUnc) {
|
||||||
|
device = normalizeUNCRoot(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
return device + (isAbsolute ? '\\' : '') + tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
win32.isAbsolute = function(path) {
|
||||||
|
var result = splitDeviceRe.exec(path),
|
||||||
|
device = result[1] || '',
|
||||||
|
isUnc = !!device && device.charAt(1) !== ':';
|
||||||
|
// UNC paths are always absolute
|
||||||
|
return !!result[2] || isUnc;
|
||||||
|
};
|
||||||
|
|
||||||
|
win32.join = function() {
|
||||||
|
function f(p) {
|
||||||
|
if (!util.isString(p)) {
|
||||||
|
throw new TypeError('Arguments to path.join must be strings');
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
var paths = Array.prototype.filter.call(arguments, f);
|
||||||
|
var joined = paths.join('\\');
|
||||||
|
|
||||||
|
// Make sure that the joined path doesn't start with two slashes, because
|
||||||
|
// normalize() will mistake it for an UNC path then.
|
||||||
|
//
|
||||||
|
// This step is skipped when it is very clear that the user actually
|
||||||
|
// intended to point at an UNC path. This is assumed when the first
|
||||||
|
// non-empty string arguments starts with exactly two slashes followed by
|
||||||
|
// at least one more non-slash character.
|
||||||
|
//
|
||||||
|
// Note that for normalize() to treat a path as an UNC path it needs to
|
||||||
|
// have at least 2 components, so we don't filter for that here.
|
||||||
|
// This means that the user can use join to construct UNC paths from
|
||||||
|
// a server name and a share name; for example:
|
||||||
|
// path.join('//server', 'share') -> '\\\\server\\share\')
|
||||||
|
if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
|
||||||
|
joined = joined.replace(/^[\\\/]{2,}/, '\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
return win32.normalize(joined);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// path.relative(from, to)
|
||||||
|
// it will solve the relative path from 'from' to 'to', for instance:
|
||||||
|
// from = 'C:\\orandea\\test\\aaa'
|
||||||
|
// to = 'C:\\orandea\\impl\\bbb'
|
||||||
|
// The output of the function should be: '..\\..\\impl\\bbb'
|
||||||
|
win32.relative = function(from, to) {
|
||||||
|
from = win32.resolve(from);
|
||||||
|
to = win32.resolve(to);
|
||||||
|
|
||||||
|
// windows is not case sensitive
|
||||||
|
var lowerFrom = from.toLowerCase();
|
||||||
|
var lowerTo = to.toLowerCase();
|
||||||
|
|
||||||
|
function trim(arr) {
|
||||||
|
var start = 0;
|
||||||
|
for (; start < arr.length; start++) {
|
||||||
|
if (arr[start] !== '') break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return device + (isAbsolute ? '\\' : '') + tail;
|
var end = arr.length - 1;
|
||||||
};
|
for (; end >= 0; end--) {
|
||||||
|
if (arr[end] !== '') break;
|
||||||
// windows version
|
|
||||||
exports.isAbsolute = function(path) {
|
|
||||||
var result = splitDeviceRe.exec(path),
|
|
||||||
device = result[1] || '',
|
|
||||||
isUnc = !!device && device.charAt(1) !== ':';
|
|
||||||
// UNC paths are always absolute
|
|
||||||
return !!result[2] || isUnc;
|
|
||||||
};
|
|
||||||
|
|
||||||
// windows version
|
|
||||||
exports.join = function() {
|
|
||||||
function f(p) {
|
|
||||||
if (!util.isString(p)) {
|
|
||||||
throw new TypeError('Arguments to path.join must be strings');
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var paths = Array.prototype.filter.call(arguments, f);
|
if (start > end) return [];
|
||||||
var joined = paths.join('\\');
|
return arr.slice(start, end + 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that the joined path doesn't start with two slashes, because
|
var toParts = trim(to.split('\\'));
|
||||||
// normalize() will mistake it for an UNC path then.
|
|
||||||
//
|
var lowerFromParts = trim(lowerFrom.split('\\'));
|
||||||
// This step is skipped when it is very clear that the user actually
|
var lowerToParts = trim(lowerTo.split('\\'));
|
||||||
// intended to point at an UNC path. This is assumed when the first
|
|
||||||
// non-empty string arguments starts with exactly two slashes followed by
|
var length = Math.min(lowerFromParts.length, lowerToParts.length);
|
||||||
// at least one more non-slash character.
|
var samePartsLength = length;
|
||||||
//
|
for (var i = 0; i < length; i++) {
|
||||||
// Note that for normalize() to treat a path as an UNC path it needs to
|
if (lowerFromParts[i] !== lowerToParts[i]) {
|
||||||
// have at least 2 components, so we don't filter for that here.
|
samePartsLength = i;
|
||||||
// This means that the user can use join to construct UNC paths from
|
break;
|
||||||
// a server name and a share name; for example:
|
|
||||||
// path.join('//server', 'share') -> '\\\\server\\share\')
|
|
||||||
if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
|
|
||||||
joined = joined.replace(/^[\\\/]{2,}/, '\\');
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return exports.normalize(joined);
|
if (samePartsLength == 0) {
|
||||||
};
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
// path.relative(from, to)
|
var outputParts = [];
|
||||||
// it will solve the relative path from 'from' to 'to', for instance:
|
for (var i = samePartsLength; i < lowerFromParts.length; i++) {
|
||||||
// from = 'C:\\orandea\\test\\aaa'
|
outputParts.push('..');
|
||||||
// to = 'C:\\orandea\\impl\\bbb'
|
}
|
||||||
// The output of the function should be: '..\\..\\impl\\bbb'
|
|
||||||
// windows version
|
|
||||||
exports.relative = function(from, to) {
|
|
||||||
from = exports.resolve(from);
|
|
||||||
to = exports.resolve(to);
|
|
||||||
|
|
||||||
// windows is not case sensitive
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
||||||
var lowerFrom = from.toLowerCase();
|
|
||||||
var lowerTo = to.toLowerCase();
|
|
||||||
|
|
||||||
function trim(arr) {
|
return outputParts.join('\\');
|
||||||
var start = 0;
|
};
|
||||||
for (; start < arr.length; start++) {
|
|
||||||
if (arr[start] !== '') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var end = arr.length - 1;
|
|
||||||
for (; end >= 0; end--) {
|
|
||||||
if (arr[end] !== '') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start > end) return [];
|
|
||||||
return arr.slice(start, end + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var toParts = trim(to.split('\\'));
|
|
||||||
|
|
||||||
var lowerFromParts = trim(lowerFrom.split('\\'));
|
|
||||||
var lowerToParts = trim(lowerTo.split('\\'));
|
|
||||||
|
|
||||||
var length = Math.min(lowerFromParts.length, lowerToParts.length);
|
|
||||||
var samePartsLength = length;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
if (lowerFromParts[i] !== lowerToParts[i]) {
|
|
||||||
samePartsLength = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (samePartsLength == 0) {
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
var outputParts = [];
|
|
||||||
for (var i = samePartsLength; i < lowerFromParts.length; i++) {
|
|
||||||
outputParts.push('..');
|
|
||||||
}
|
|
||||||
|
|
||||||
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
|
||||||
|
|
||||||
return outputParts.join('\\');
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.sep = '\\';
|
|
||||||
exports.delimiter = ';';
|
|
||||||
|
|
||||||
} else /* posix */ {
|
|
||||||
|
|
||||||
// Split a filename into [root, dir, basename, ext], unix version
|
|
||||||
// 'root' is just a slash, or nothing.
|
|
||||||
var splitPathRe =
|
|
||||||
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
|
|
||||||
var splitPath = function(filename) {
|
|
||||||
return splitPathRe.exec(filename).slice(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// path.resolve([from ...], to)
|
|
||||||
// posix version
|
|
||||||
exports.resolve = function() {
|
|
||||||
var resolvedPath = '',
|
|
||||||
resolvedAbsolute = false;
|
|
||||||
|
|
||||||
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|
||||||
var path = (i >= 0) ? arguments[i] : process.cwd();
|
|
||||||
|
|
||||||
// Skip empty and invalid entries
|
|
||||||
if (!util.isString(path)) {
|
|
||||||
throw new TypeError('Arguments to path.resolve must be strings');
|
|
||||||
} else if (!path) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedPath = path + '/' + resolvedPath;
|
|
||||||
resolvedAbsolute = path.charAt(0) === '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point the path should be resolved to a full absolute path, but
|
|
||||||
// handle relative paths to be safe (might happen when process.cwd() fails)
|
|
||||||
|
|
||||||
// Normalize the path
|
|
||||||
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
|
|
||||||
return !!p;
|
|
||||||
}), !resolvedAbsolute).join('/');
|
|
||||||
|
|
||||||
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
|
||||||
};
|
|
||||||
|
|
||||||
// path.normalize(path)
|
|
||||||
// posix version
|
|
||||||
exports.normalize = function(path) {
|
|
||||||
var isAbsolute = exports.isAbsolute(path),
|
|
||||||
trailingSlash = path[path.length - 1] === '/',
|
|
||||||
segments = path.split('/'),
|
|
||||||
nonEmptySegments = [];
|
|
||||||
|
|
||||||
// Normalize the path
|
|
||||||
for (var i = 0; i < segments.length; i++) {
|
|
||||||
if (segments[i]) {
|
|
||||||
nonEmptySegments.push(segments[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path = normalizeArray(nonEmptySegments, !isAbsolute).join('/');
|
|
||||||
|
|
||||||
if (!path && !isAbsolute) {
|
|
||||||
path = '.';
|
|
||||||
}
|
|
||||||
if (path && trailingSlash) {
|
|
||||||
path += '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (isAbsolute ? '/' : '') + path;
|
|
||||||
};
|
|
||||||
|
|
||||||
// posix version
|
|
||||||
exports.isAbsolute = function(path) {
|
|
||||||
return path.charAt(0) === '/';
|
|
||||||
};
|
|
||||||
|
|
||||||
// posix version
|
|
||||||
exports.join = function() {
|
|
||||||
var path = '';
|
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
|
||||||
var segment = arguments[i];
|
|
||||||
if (!util.isString(segment)) {
|
|
||||||
throw new TypeError('Arguments to path.join must be strings');
|
|
||||||
}
|
|
||||||
if (segment) {
|
|
||||||
if (!path) {
|
|
||||||
path += segment;
|
|
||||||
} else {
|
|
||||||
path += '/' + segment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exports.normalize(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// path.relative(from, to)
|
win32._makeLong = function(path) {
|
||||||
// posix version
|
// Note: this will *probably* throw somewhere.
|
||||||
exports.relative = function(from, to) {
|
if (!util.isString(path))
|
||||||
from = exports.resolve(from).substr(1);
|
return path;
|
||||||
to = exports.resolve(to).substr(1);
|
|
||||||
|
|
||||||
function trim(arr) {
|
if (!path) {
|
||||||
var start = 0;
|
return '';
|
||||||
for (; start < arr.length; start++) {
|
}
|
||||||
if (arr[start] !== '') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var end = arr.length - 1;
|
var resolvedPath = win32.resolve(path);
|
||||||
for (; end >= 0; end--) {
|
|
||||||
if (arr[end] !== '') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start > end) return [];
|
if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
|
||||||
return arr.slice(start, end + 1);
|
// path is local filesystem path, which needs to be converted
|
||||||
}
|
// to long UNC path.
|
||||||
|
return '\\\\?\\' + resolvedPath;
|
||||||
|
} else if (/^\\\\[^?.]/.test(resolvedPath)) {
|
||||||
|
// path is network UNC path, which needs to be converted
|
||||||
|
// to long UNC path.
|
||||||
|
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
var fromParts = trim(from.split('/'));
|
return path;
|
||||||
var toParts = trim(to.split('/'));
|
};
|
||||||
|
|
||||||
var length = Math.min(fromParts.length, toParts.length);
|
|
||||||
var samePartsLength = length;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
if (fromParts[i] !== toParts[i]) {
|
|
||||||
samePartsLength = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var outputParts = [];
|
win32.dirname = function(path) {
|
||||||
for (var i = samePartsLength; i < fromParts.length; i++) {
|
var result = win32.splitPath(path),
|
||||||
outputParts.push('..');
|
|
||||||
}
|
|
||||||
|
|
||||||
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
|
||||||
|
|
||||||
return outputParts.join('/');
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.sep = '/';
|
|
||||||
exports.delimiter = ':';
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.dirname = function(path) {
|
|
||||||
var result = splitPath(path),
|
|
||||||
root = result[0],
|
root = result[0],
|
||||||
dir = result[1];
|
dir = result[1];
|
||||||
|
|
||||||
@ -467,8 +349,8 @@ exports.dirname = function(path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.basename = function(path, ext) {
|
win32.basename = function(path, ext) {
|
||||||
var f = splitPath(path)[2];
|
var f = win32.splitPath(path)[2];
|
||||||
// TODO: make this comparison case-insensitive on windows?
|
// TODO: make this comparison case-insensitive on windows?
|
||||||
if (ext && f.substr(-1 * ext.length) === ext) {
|
if (ext && f.substr(-1 * ext.length) === ext) {
|
||||||
f = f.substr(0, f.length - ext.length);
|
f = f.substr(0, f.length - ext.length);
|
||||||
@ -477,47 +359,200 @@ exports.basename = function(path, ext) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.extname = function(path) {
|
win32.extname = function(path) {
|
||||||
return splitPath(path)[3];
|
return win32.splitPath(path)[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.exists = util.deprecate(function(path, callback) {
|
win32.sep = '\\';
|
||||||
require('fs').exists(path, callback);
|
win32.delimiter = ';';
|
||||||
}, 'path.exists is now called `fs.exists`.');
|
|
||||||
|
|
||||||
|
|
||||||
exports.existsSync = util.deprecate(function(path) {
|
// Split a filename into [root, dir, basename, ext], unix version
|
||||||
return require('fs').existsSync(path);
|
// 'root' is just a slash, or nothing.
|
||||||
}, 'path.existsSync is now called `fs.existsSync`.');
|
var splitPathRe =
|
||||||
|
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
|
||||||
|
var posix = {};
|
||||||
|
|
||||||
|
|
||||||
if (isWindows) {
|
posix.splitPath = function(filename) {
|
||||||
exports._makeLong = function(path) {
|
return splitPathRe.exec(filename).slice(1);
|
||||||
// Note: this will *probably* throw somewhere.
|
};
|
||||||
if (!util.isString(path))
|
|
||||||
return path;
|
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
return '';
|
// path.resolve([from ...], to)
|
||||||
|
// posix version
|
||||||
|
posix.resolve = function() {
|
||||||
|
var resolvedPath = '',
|
||||||
|
resolvedAbsolute = false;
|
||||||
|
|
||||||
|
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
||||||
|
var path = (i >= 0) ? arguments[i] : process.cwd();
|
||||||
|
|
||||||
|
// Skip empty and invalid entries
|
||||||
|
if (!util.isString(path)) {
|
||||||
|
throw new TypeError('Arguments to path.resolve must be strings');
|
||||||
|
} else if (!path) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var resolvedPath = exports.resolve(path);
|
resolvedPath = path + '/' + resolvedPath;
|
||||||
|
resolvedAbsolute = path.charAt(0) === '/';
|
||||||
|
}
|
||||||
|
|
||||||
if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
|
// At this point the path should be resolved to a full absolute path, but
|
||||||
// path is local filesystem path, which needs to be converted
|
// handle relative paths to be safe (might happen when process.cwd() fails)
|
||||||
// to long UNC path.
|
|
||||||
return '\\\\?\\' + resolvedPath;
|
// Normalize the path
|
||||||
} else if (/^\\\\[^?.]/.test(resolvedPath)) {
|
resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
|
||||||
// path is network UNC path, which needs to be converted
|
return !!p;
|
||||||
// to long UNC path.
|
}), !resolvedAbsolute).join('/');
|
||||||
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
|
|
||||||
|
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
||||||
|
};
|
||||||
|
|
||||||
|
// path.normalize(path)
|
||||||
|
// posix version
|
||||||
|
posix.normalize = function(path) {
|
||||||
|
var isAbsolute = posix.isAbsolute(path),
|
||||||
|
trailingSlash = path.substr(-1) === '/',
|
||||||
|
segments = path.split('/'),
|
||||||
|
nonEmptySegments = [];
|
||||||
|
|
||||||
|
// Normalize the path
|
||||||
|
for (var i = 0; i < segments.length; i++) {
|
||||||
|
if (segments[i]) {
|
||||||
|
nonEmptySegments.push(segments[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path = normalizeArray(nonEmptySegments, !isAbsolute).join('/');
|
||||||
|
|
||||||
|
if (!path && !isAbsolute) {
|
||||||
|
path = '.';
|
||||||
|
}
|
||||||
|
if (path && trailingSlash) {
|
||||||
|
path += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (isAbsolute ? '/' : '') + path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// posix version
|
||||||
|
posix.isAbsolute = function(path) {
|
||||||
|
return path.charAt(0) === '/';
|
||||||
|
};
|
||||||
|
|
||||||
|
// posix version
|
||||||
|
posix.join = function() {
|
||||||
|
var path = '';
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
var segment = arguments[i];
|
||||||
|
if (!util.isString(segment)) {
|
||||||
|
throw new TypeError('Arguments to path.join must be strings');
|
||||||
|
}
|
||||||
|
if (segment) {
|
||||||
|
if (!path) {
|
||||||
|
path += segment;
|
||||||
|
} else {
|
||||||
|
path += '/' + segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return posix.normalize(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// path.relative(from, to)
|
||||||
|
// posix version
|
||||||
|
posix.relative = function(from, to) {
|
||||||
|
from = posix.resolve(from).substr(1);
|
||||||
|
to = posix.resolve(to).substr(1);
|
||||||
|
|
||||||
|
function trim(arr) {
|
||||||
|
var start = 0;
|
||||||
|
for (; start < arr.length; start++) {
|
||||||
|
if (arr[start] !== '') break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
var end = arr.length - 1;
|
||||||
};
|
for (; end >= 0; end--) {
|
||||||
} else {
|
if (arr[end] !== '') break;
|
||||||
exports._makeLong = function(path) {
|
}
|
||||||
return path;
|
|
||||||
};
|
if (start > end) return [];
|
||||||
}
|
return arr.slice(start, end + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fromParts = trim(from.split('/'));
|
||||||
|
var toParts = trim(to.split('/'));
|
||||||
|
|
||||||
|
var length = Math.min(fromParts.length, toParts.length);
|
||||||
|
var samePartsLength = length;
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
if (fromParts[i] !== toParts[i]) {
|
||||||
|
samePartsLength = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputParts = [];
|
||||||
|
for (var i = samePartsLength; i < fromParts.length; i++) {
|
||||||
|
outputParts.push('..');
|
||||||
|
}
|
||||||
|
|
||||||
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
||||||
|
|
||||||
|
return outputParts.join('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
posix._makeLong = function(path) {
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
posix.dirname = function(path) {
|
||||||
|
var result = posix.splitPath(path),
|
||||||
|
root = result[0],
|
||||||
|
dir = result[1];
|
||||||
|
|
||||||
|
if (!root && !dir) {
|
||||||
|
// No dirname whatsoever
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir) {
|
||||||
|
// It has a dirname, strip trailing slash
|
||||||
|
dir = dir.substr(0, dir.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root + dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
posix.basename = function(path, ext) {
|
||||||
|
var f = posix.splitPath(path)[2];
|
||||||
|
// TODO: make this comparison case-insensitive on windows?
|
||||||
|
if (ext && f.substr(-1 * ext.length) === ext) {
|
||||||
|
f = f.substr(0, f.length - ext.length);
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
posix.extname = function(path) {
|
||||||
|
return posix.splitPath(path)[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
posix.sep = '/';
|
||||||
|
posix.delimiter = ':';
|
||||||
|
|
||||||
|
|
||||||
|
if (isWindows)
|
||||||
|
module.exports = win32;
|
||||||
|
else /* posix */
|
||||||
|
module.exports = posix;
|
||||||
|
|
||||||
|
module.exports.posix = posix;
|
||||||
|
module.exports.win32 = win32;
|
||||||
|
@ -37,22 +37,19 @@ assert.equal(path.basename('basename.ext'), 'basename.ext');
|
|||||||
assert.equal(path.basename('basename.ext/'), 'basename.ext');
|
assert.equal(path.basename('basename.ext/'), 'basename.ext');
|
||||||
assert.equal(path.basename('basename.ext//'), 'basename.ext');
|
assert.equal(path.basename('basename.ext//'), 'basename.ext');
|
||||||
|
|
||||||
if (isWindows) {
|
// On Windows a backslash acts as a path separator.
|
||||||
// On Windows a backslash acts as a path separator.
|
assert.equal(path.win32.basename('\\dir\\basename.ext'), 'basename.ext');
|
||||||
assert.equal(path.basename('\\dir\\basename.ext'), 'basename.ext');
|
assert.equal(path.win32.basename('\\basename.ext'), 'basename.ext');
|
||||||
assert.equal(path.basename('\\basename.ext'), 'basename.ext');
|
assert.equal(path.win32.basename('basename.ext'), 'basename.ext');
|
||||||
assert.equal(path.basename('basename.ext'), 'basename.ext');
|
assert.equal(path.win32.basename('basename.ext\\'), 'basename.ext');
|
||||||
assert.equal(path.basename('basename.ext\\'), 'basename.ext');
|
assert.equal(path.win32.basename('basename.ext\\\\'), 'basename.ext');
|
||||||
assert.equal(path.basename('basename.ext\\\\'), 'basename.ext');
|
|
||||||
|
|
||||||
} else {
|
// On unix a backslash is just treated as any other character.
|
||||||
// On unix a backslash is just treated as any other character.
|
assert.equal(path.posix.basename('\\dir\\basename.ext'), '\\dir\\basename.ext');
|
||||||
assert.equal(path.basename('\\dir\\basename.ext'), '\\dir\\basename.ext');
|
assert.equal(path.posix.basename('\\basename.ext'), '\\basename.ext');
|
||||||
assert.equal(path.basename('\\basename.ext'), '\\basename.ext');
|
assert.equal(path.posix.basename('basename.ext'), 'basename.ext');
|
||||||
assert.equal(path.basename('basename.ext'), 'basename.ext');
|
assert.equal(path.posix.basename('basename.ext\\'), 'basename.ext\\');
|
||||||
assert.equal(path.basename('basename.ext\\'), 'basename.ext\\');
|
assert.equal(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\');
|
||||||
assert.equal(path.basename('basename.ext\\\\'), 'basename.ext\\\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
// POSIX filenames may include control characters
|
// POSIX filenames may include control characters
|
||||||
// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
|
// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html
|
||||||
@ -73,35 +70,33 @@ assert.equal(path.dirname(''), '.');
|
|||||||
assert.equal(path.dirname('/'), '/');
|
assert.equal(path.dirname('/'), '/');
|
||||||
assert.equal(path.dirname('////'), '/');
|
assert.equal(path.dirname('////'), '/');
|
||||||
|
|
||||||
if (isWindows) {
|
assert.equal(path.win32.dirname('c:\\'), 'c:\\');
|
||||||
assert.equal(path.dirname('c:\\'), 'c:\\');
|
assert.equal(path.win32.dirname('c:\\foo'), 'c:\\');
|
||||||
assert.equal(path.dirname('c:\\foo'), 'c:\\');
|
assert.equal(path.win32.dirname('c:\\foo\\'), 'c:\\');
|
||||||
assert.equal(path.dirname('c:\\foo\\'), 'c:\\');
|
assert.equal(path.win32.dirname('c:\\foo\\bar'), 'c:\\foo');
|
||||||
assert.equal(path.dirname('c:\\foo\\bar'), 'c:\\foo');
|
assert.equal(path.win32.dirname('c:\\foo\\bar\\'), 'c:\\foo');
|
||||||
assert.equal(path.dirname('c:\\foo\\bar\\'), 'c:\\foo');
|
assert.equal(path.win32.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar');
|
||||||
assert.equal(path.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar');
|
assert.equal(path.win32.dirname('\\'), '\\');
|
||||||
assert.equal(path.dirname('\\'), '\\');
|
assert.equal(path.win32.dirname('\\foo'), '\\');
|
||||||
assert.equal(path.dirname('\\foo'), '\\');
|
assert.equal(path.win32.dirname('\\foo\\'), '\\');
|
||||||
assert.equal(path.dirname('\\foo\\'), '\\');
|
assert.equal(path.win32.dirname('\\foo\\bar'), '\\foo');
|
||||||
assert.equal(path.dirname('\\foo\\bar'), '\\foo');
|
assert.equal(path.win32.dirname('\\foo\\bar\\'), '\\foo');
|
||||||
assert.equal(path.dirname('\\foo\\bar\\'), '\\foo');
|
assert.equal(path.win32.dirname('\\foo\\bar\\baz'), '\\foo\\bar');
|
||||||
assert.equal(path.dirname('\\foo\\bar\\baz'), '\\foo\\bar');
|
assert.equal(path.win32.dirname('c:'), 'c:');
|
||||||
assert.equal(path.dirname('c:'), 'c:');
|
assert.equal(path.win32.dirname('c:foo'), 'c:');
|
||||||
assert.equal(path.dirname('c:foo'), 'c:');
|
assert.equal(path.win32.dirname('c:foo\\'), 'c:');
|
||||||
assert.equal(path.dirname('c:foo\\'), 'c:');
|
assert.equal(path.win32.dirname('c:foo\\bar'), 'c:foo');
|
||||||
assert.equal(path.dirname('c:foo\\bar'), 'c:foo');
|
assert.equal(path.win32.dirname('c:foo\\bar\\'), 'c:foo');
|
||||||
assert.equal(path.dirname('c:foo\\bar\\'), 'c:foo');
|
assert.equal(path.win32.dirname('c:foo\\bar\\baz'), 'c:foo\\bar');
|
||||||
assert.equal(path.dirname('c:foo\\bar\\baz'), 'c:foo\\bar');
|
assert.equal(path.win32.dirname('\\\\unc\\share'), '\\\\unc\\share');
|
||||||
assert.equal(path.dirname('\\\\unc\\share'), '\\\\unc\\share');
|
assert.equal(path.win32.dirname('\\\\unc\\share\\foo'), '\\\\unc\\share\\');
|
||||||
assert.equal(path.dirname('\\\\unc\\share\\foo'), '\\\\unc\\share\\');
|
assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\'), '\\\\unc\\share\\');
|
||||||
assert.equal(path.dirname('\\\\unc\\share\\foo\\'), '\\\\unc\\share\\');
|
assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\bar'),
|
||||||
assert.equal(path.dirname('\\\\unc\\share\\foo\\bar'),
|
'\\\\unc\\share\\foo');
|
||||||
'\\\\unc\\share\\foo');
|
assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'),
|
||||||
assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\'),
|
'\\\\unc\\share\\foo');
|
||||||
'\\\\unc\\share\\foo');
|
assert.equal(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'),
|
||||||
assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\baz'),
|
'\\\\unc\\share\\foo\\bar');
|
||||||
'\\\\unc\\share\\foo\\bar');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
assert.equal(path.extname(''), '');
|
assert.equal(path.extname(''), '');
|
||||||
@ -146,28 +141,25 @@ assert.equal(path.extname('file//'), '');
|
|||||||
assert.equal(path.extname('file./'), '.');
|
assert.equal(path.extname('file./'), '.');
|
||||||
assert.equal(path.extname('file.//'), '.');
|
assert.equal(path.extname('file.//'), '.');
|
||||||
|
|
||||||
if (isWindows) {
|
// On windows, backspace is a path separator.
|
||||||
// On windows, backspace is a path separator.
|
assert.equal(path.win32.extname('.\\'), '');
|
||||||
assert.equal(path.extname('.\\'), '');
|
assert.equal(path.win32.extname('..\\'), '');
|
||||||
assert.equal(path.extname('..\\'), '');
|
assert.equal(path.win32.extname('file.ext\\'), '.ext');
|
||||||
assert.equal(path.extname('file.ext\\'), '.ext');
|
assert.equal(path.win32.extname('file.ext\\\\'), '.ext');
|
||||||
assert.equal(path.extname('file.ext\\\\'), '.ext');
|
assert.equal(path.win32.extname('file\\'), '');
|
||||||
assert.equal(path.extname('file\\'), '');
|
assert.equal(path.win32.extname('file\\\\'), '');
|
||||||
assert.equal(path.extname('file\\\\'), '');
|
assert.equal(path.win32.extname('file.\\'), '.');
|
||||||
assert.equal(path.extname('file.\\'), '.');
|
assert.equal(path.win32.extname('file.\\\\'), '.');
|
||||||
assert.equal(path.extname('file.\\\\'), '.');
|
|
||||||
|
|
||||||
} else {
|
// On unix, backspace is a valid name component like any other character.
|
||||||
// On unix, backspace is a valid name component like any other character.
|
assert.equal(path.posix.extname('.\\'), '');
|
||||||
assert.equal(path.extname('.\\'), '');
|
assert.equal(path.posix.extname('..\\'), '.\\');
|
||||||
assert.equal(path.extname('..\\'), '.\\');
|
assert.equal(path.posix.extname('file.ext\\'), '.ext\\');
|
||||||
assert.equal(path.extname('file.ext\\'), '.ext\\');
|
assert.equal(path.posix.extname('file.ext\\\\'), '.ext\\\\');
|
||||||
assert.equal(path.extname('file.ext\\\\'), '.ext\\\\');
|
assert.equal(path.posix.extname('file\\'), '');
|
||||||
assert.equal(path.extname('file\\'), '');
|
assert.equal(path.posix.extname('file\\\\'), '');
|
||||||
assert.equal(path.extname('file\\\\'), '');
|
assert.equal(path.posix.extname('file.\\'), '.\\');
|
||||||
assert.equal(path.extname('file.\\'), '.\\');
|
assert.equal(path.posix.extname('file.\\\\'), '.\\\\');
|
||||||
assert.equal(path.extname('file.\\\\'), '.\\\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
// path.join tests
|
// path.join tests
|
||||||
var failures = [];
|
var failures = [];
|
||||||
@ -294,23 +286,21 @@ joinThrowTests.forEach(function(test) {
|
|||||||
|
|
||||||
|
|
||||||
// path normalize tests
|
// path normalize tests
|
||||||
if (isWindows) {
|
assert.equal(path.win32.normalize('./fixtures///b/../b/c.js'),
|
||||||
assert.equal(path.normalize('./fixtures///b/../b/c.js'),
|
'fixtures\\b\\c.js');
|
||||||
'fixtures\\b\\c.js');
|
assert.equal(path.win32.normalize('/foo/../../../bar'), '\\bar');
|
||||||
assert.equal(path.normalize('/foo/../../../bar'), '\\bar');
|
assert.equal(path.win32.normalize('a//b//../b'), 'a\\b');
|
||||||
assert.equal(path.normalize('a//b//../b'), 'a\\b');
|
assert.equal(path.win32.normalize('a//b//./c'), 'a\\b\\c');
|
||||||
assert.equal(path.normalize('a//b//./c'), 'a\\b\\c');
|
assert.equal(path.win32.normalize('a//b//.'), 'a\\b');
|
||||||
assert.equal(path.normalize('a//b//.'), 'a\\b');
|
assert.equal(path.win32.normalize('//server/share/dir/file.ext'),
|
||||||
assert.equal(path.normalize('//server/share/dir/file.ext'),
|
'\\\\server\\share\\dir\\file.ext');
|
||||||
'\\\\server\\share\\dir\\file.ext');
|
|
||||||
} else {
|
assert.equal(path.posix.normalize('./fixtures///b/../b/c.js'),
|
||||||
assert.equal(path.normalize('./fixtures///b/../b/c.js'),
|
'fixtures/b/c.js');
|
||||||
'fixtures/b/c.js');
|
assert.equal(path.posix.normalize('/foo/../../../bar'), '/bar');
|
||||||
assert.equal(path.normalize('/foo/../../../bar'), '/bar');
|
assert.equal(path.posix.normalize('a//b//../b'), 'a/b');
|
||||||
assert.equal(path.normalize('a//b//../b'), 'a/b');
|
assert.equal(path.posix.normalize('a//b//./c'), 'a/b/c');
|
||||||
assert.equal(path.normalize('a//b//./c'), 'a/b/c');
|
assert.equal(path.posix.normalize('a//b//.'), 'a/b');
|
||||||
assert.equal(path.normalize('a//b//.'), 'a/b');
|
|
||||||
}
|
|
||||||
|
|
||||||
// path.resolve tests
|
// path.resolve tests
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
@ -352,21 +342,19 @@ resolveTests.forEach(function(test) {
|
|||||||
assert.equal(failures.length, 0, failures.join(''));
|
assert.equal(failures.length, 0, failures.join(''));
|
||||||
|
|
||||||
// path.isAbsolute tests
|
// path.isAbsolute tests
|
||||||
if (isWindows) {
|
assert.equal(path.win32.isAbsolute('//server/file'), true);
|
||||||
assert.equal(path.isAbsolute('//server/file'), true);
|
assert.equal(path.win32.isAbsolute('\\\\server\\file'), true);
|
||||||
assert.equal(path.isAbsolute('\\\\server\\file'), true);
|
assert.equal(path.win32.isAbsolute('C:/Users/'), true);
|
||||||
assert.equal(path.isAbsolute('C:/Users/'), true);
|
assert.equal(path.win32.isAbsolute('C:\\Users\\'), true);
|
||||||
assert.equal(path.isAbsolute('C:\\Users\\'), true);
|
assert.equal(path.win32.isAbsolute('C:cwd/another'), false);
|
||||||
assert.equal(path.isAbsolute('C:cwd/another'), false);
|
assert.equal(path.win32.isAbsolute('C:cwd\\another'), false);
|
||||||
assert.equal(path.isAbsolute('C:cwd\\another'), false);
|
assert.equal(path.win32.isAbsolute('directory/directory'), false);
|
||||||
assert.equal(path.isAbsolute('directory/directory'), false);
|
assert.equal(path.win32.isAbsolute('directory\\directory'), false);
|
||||||
assert.equal(path.isAbsolute('directory\\directory'), false);
|
|
||||||
} else {
|
assert.equal(path.posix.isAbsolute('/home/foo'), true);
|
||||||
assert.equal(path.isAbsolute('/home/foo'), true);
|
assert.equal(path.posix.isAbsolute('/home/foo/..'), true);
|
||||||
assert.equal(path.isAbsolute('/home/foo/..'), true);
|
assert.equal(path.posix.isAbsolute('bar/'), false);
|
||||||
assert.equal(path.isAbsolute('bar/'), false);
|
assert.equal(path.posix.isAbsolute('./baz'), false);
|
||||||
assert.equal(path.isAbsolute('./baz'), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// path.relative tests
|
// path.relative tests
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
@ -405,20 +393,20 @@ relativeTests.forEach(function(test) {
|
|||||||
});
|
});
|
||||||
assert.equal(failures.length, 0, failures.join(''));
|
assert.equal(failures.length, 0, failures.join(''));
|
||||||
|
|
||||||
// path.sep tests
|
// windows
|
||||||
if (isWindows) {
|
assert.equal(path.win32.sep, '\\');
|
||||||
// windows
|
// posix
|
||||||
assert.equal(path.sep, '\\');
|
assert.equal(path.posix.sep, '/');
|
||||||
} else {
|
|
||||||
// posix
|
|
||||||
assert.equal(path.sep, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// path.delimiter tests
|
// path.delimiter tests
|
||||||
if (isWindows) {
|
// windows
|
||||||
// windows
|
assert.equal(path.win32.delimiter, ';');
|
||||||
assert.equal(path.delimiter, ';');
|
|
||||||
} else {
|
// posix
|
||||||
// posix
|
assert.equal(path.posix.delimiter, ':');
|
||||||
assert.equal(path.delimiter, ':');
|
|
||||||
}
|
|
||||||
|
if (isWindows)
|
||||||
|
assert.deepEqual(path, path.win32, 'should be win32 path module');
|
||||||
|
else
|
||||||
|
assert.deepEqual(path, path.posix, 'should be posix path module');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user