Skip to content

Commit

Permalink
path: path.common
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Feb 14, 2014
1 parent e8df267 commit c4c96de
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
88 changes: 88 additions & 0 deletions lib/path.js
Expand Up @@ -84,6 +84,16 @@ if (isWindows) {
return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
};

var normalizeForCommon = function (path) {
if (!util.isString(path)) {
throw new TypeError('Arguments to path.common must be strings');
}
var isDir = (path[path.length - 1] === '\\');
path = exports.resolve(path);
if (isDir) return path;
return exports.dirname(path);
};

// path.resolve([from ...], to)
// windows version
exports.resolve = function() {
Expand Down Expand Up @@ -300,6 +310,40 @@ if (isWindows) {
return outputParts.join('\\');
};

// path.common(path1/*, ...pathn*/)
// windows version
exports.common = function(path/*, ...pathn*/) {
path = normalizeForCommon(path);
var i = 1;
var l = arguments.length;
var pathLength = path.length;
for (; i < l; ++i) {
var other = normalizeForCommon(arguments[i]);
var end = 0;
var j = 0;
var otherLength = other.length;
while (path[j] === other[j]) {
if (path[j] === '\\') end = j;
++j;
if (pathLength === j) {
if (otherLength === j) end = j;
else if (other[j] === '\\') end = j;
break;
}
if (otherLength === j) {
if (path[j] === '\\') end = j;
break;
}
}
if (!end) return null;
if (end !== pathLength) {
path = path.slice(0, end);
pathLength = end;
}
}
return path;
};

exports.sep = '\\';
exports.delimiter = ';';

Expand All @@ -312,6 +356,15 @@ if (isWindows) {
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
var normalizeForCommon = function (path) {
if (!util.isString(path)) {
throw new TypeError('Arguments to path.common must be strings');
}
var isDir = (path[path.length - 1] === '/');
path = exports.resolve(path);
if (isDir) return path;
return exports.dirname(path);
};

// path.resolve([from ...], to)
// posix version
Expand Down Expand Up @@ -438,6 +491,41 @@ if (isWindows) {
return outputParts.join('/');
};

// path.common(path1/*, ...pathn*/)
// posix version
exports.common = function(path/*, ...pathn*/) {
path = normalizeForCommon(path);
if (path === '/') return '/';
var i = 1;
var l = arguments.length;
var pathLength = path.length;
for (; i < l; ++i) {
var other = normalizeForCommon(arguments[i]);
var end = 0;
var j = 0;
var otherLength = other.length;
while (path[j] === other[j]) {
if (path[j] === '/') end = j;
++j;
if (pathLength === j) {
if (otherLength === j) end = j;
else if (other[j] === '/') end = j;
break;
}
if (otherLength === j) {
if (path[j] === '/') end = j;
break;
}
}
if (end <= 1) return '/';
if (end !== pathLength) {
path = path.slice(0, end);
pathLength = end;
}
}
return path;
};

exports.sep = '/';
exports.delimiter = ':';
}
Expand Down
46 changes: 46 additions & 0 deletions test/simple/test-path.js
Expand Up @@ -405,6 +405,52 @@ relativeTests.forEach(function(test) {
});
assert.equal(failures.length, 0, failures.join(''));

// path.common tests
if (isWindows) {
// windows
var resolveTests =
// arguments result
[[['C:\\'], 'C:\\'],
[['d:\\'], 'D:\\'],
[['c:\\', 'd:\\'], null],
[['c:\\raz\\dwa\\'], 'C:\\raz\\dwa'],
[['c:\\raz\\dwa'], 'C:\\raz'],
[['c:\\raz\\dwa', 'c:\\trzy\\cztery'], 'C:\\'],
[['c:\\raz\\dwa', 'c:\\raz\\trzy'], 'C:\\raz'],
[['c:\\raz\\dwa', 'c:\\raz\\dwa\\trzy', 'c:\\raz\\cztery'], 'C:\\raz'],
[['C:\\raz\\dwa\\piec', 'c:\\raz\\dwa\\trzy', 'c:\\raz\\dwa\\cztery'],
'C:\\raz\\dwa'],
[['C:\\raz\\dwa\\piec', 'c:\\raz\\dwa\\trzy', 'c:\\raz\\dwa\\'],
'C:\\raz\\dwa'],
[['c:\\raz\\dwa\\piec', 'c:\\raz\\dwa\\trzy', 'c:\\raz\\dwa'],
'C:\\raz'],
[['c:\\raz\\dwa\\trzy', 'c:\\raz\\dwatrzy'], 'C:\\raz']];
} else {
// Posix
var resolveTests =
// arguments result
[[['/'], '/'],
[['/raz/dwa/'], '/raz/dwa'],
[['/raz/dwa'], '/raz'],
[['/raz/dwa', '/trzy/cztery'], '/'],
[['/raz/dwa', '/raz/trzy'], '/raz'],
[['/raz/dwa', '/raz/dwa/trzy', '/raz/cztery'], '/raz'],
[['/raz/dwa/piec', '/raz/dwa/trzy', '/raz/dwa/cztery'], '/raz/dwa'],
[['/raz/dwa/piec', '/raz/dwa/trzy', '/raz/dwa/'], '/raz/dwa'],
[['/raz/dwa/piec', '/raz/dwa/trzy', '/raz/dwa'], '/raz'],
[['/raz/dwa/trzy', '/raz/dwatrzy'], '/raz']];
}
var failures = [];
resolveTests.forEach(function(test) {
var actual = path.common.apply(path, test[0]);
var expected = test[1];
var message = 'path.common(' + test[0].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(''));

// path.sep tests
if (isWindows) {
// windows
Expand Down

0 comments on commit c4c96de

Please sign in to comment.