add path.relative
This commit is contained in:
parent
cf78ce59b3
commit
502900c0bc
103
lib/path.js
103
lib/path.js
@ -165,6 +165,64 @@ if (isWindows) {
|
||||
return exports.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'
|
||||
// windows version
|
||||
exports.relative = function(from, to) {
|
||||
from = exports.resolve(from);
|
||||
to = exports.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;
|
||||
}
|
||||
|
||||
var end = arr.length - 1;
|
||||
for(;end >= 0; end--) {
|
||||
if (arr[end] !== '') break;
|
||||
}
|
||||
|
||||
if (start > end) return [];
|
||||
return arr.slice(start, end - start + 1);
|
||||
}
|
||||
|
||||
var fromParts = trim(from.split('\\'));
|
||||
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('\\');
|
||||
};
|
||||
|
||||
|
||||
} else /* posix */ {
|
||||
|
||||
@ -232,6 +290,51 @@ if (isWindows) {
|
||||
return p && typeof p === 'string';
|
||||
}).join('/'));
|
||||
};
|
||||
|
||||
|
||||
// path.relative(from, to)
|
||||
// posix version
|
||||
exports.relative = function(from, to) {
|
||||
from = exports.resolve(from).substr(1);
|
||||
to = exports.resolve(to).substr(1);
|
||||
|
||||
function trim(arr) {
|
||||
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 - start + 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('/');
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -147,3 +147,39 @@ resolveTests.forEach(function(test) {
|
||||
// assert.equal(actual, expected, message);
|
||||
});
|
||||
assert.equal(failures.length, 0, failures.join(''));
|
||||
|
||||
// path.relative tests
|
||||
if (isWindows) {
|
||||
// windows
|
||||
var relativeTests =
|
||||
// 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:\\']];
|
||||
} else {
|
||||
// posix
|
||||
var relativeTests =
|
||||
// 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']];
|
||||
}
|
||||
var failures = [];
|
||||
relativeTests.forEach(function(test) {
|
||||
var actual = path.relative(test[0], test[1]);
|
||||
var expected = test[2];
|
||||
var message = 'path.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.equal(failures.length, 0, failures.join(''));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user