add function to get common abs path and list of relative paths from list of abs paths

This commit is contained in:
joshuaboud 2022-06-21 17:22:29 -03:00
parent 075c1e7fc9
commit c480eca029
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E
2 changed files with 79 additions and 0 deletions

View File

@ -0,0 +1,25 @@
/**
* Get greatest common denomincator path of an array of input paths
* @param {string[]} paths - Full paths from which to get common denominator
* @returns {CommonPathObj}
*/
export function commonPath(paths) {
const pathArrs = paths.map(str => str.split('/'));
let commonArr = [...pathArrs[0]];
for (let i = 0; i < pathArrs.length; i++) {
const iDiffer = pathArrs[i].findIndex((segment, index) => segment !== commonArr[index]);
if (iDiffer !== -1)
commonArr = commonArr.slice(0, iDiffer);
if (commonArr.length <= 1)
break;
}
const common = commonArr.join('/').replace(/^(?!\/)/, '/');
const relativePaths = pathArrs.map(fullArr => fullArr.slice(commonArr.length).join('/') || '.');
return { common, relativePaths };
}
/**
* @typedef {Object} CommonPathObj
* @property {string} common - The common denominator of all paths provided
* @property {string[]} relativePaths - the input paths made relative to the common path
*/

View File

@ -0,0 +1,54 @@
import { commonPath } from "./commonPath";
describe('The commonPath function', () => {
const filesInTmpTest = [
'/tmp/test/file1',
'/tmp/test/file2',
'/tmp/test/subdir/file3',
];
const filesInTmpHello = [
'/tmp/hello/file1',
'/tmp/hello/file2',
'/tmp/hello/subdir/file3',
];
const filesInTmp = [
...filesInTmpTest,
...filesInTmpHello,
];
const filesInHome = [
'/home/jboudreau/test1',
'/home/jboudreau/test2',
'/home/jboudreau/test3',
'/home/jboudreau/test/1/2/3/4',
'/home/mhooper/1/2/3/4',
]
const allFiles = [
...filesInTmp,
...filesInHome,
'/file',
'/',
]
it('can get the expected common denominator path from a list of inputs', () => {
expect(commonPath(filesInTmpTest).common).toEqual('/tmp/test');
expect(commonPath(filesInTmpHello).common).toEqual('/tmp/hello');
expect(commonPath(filesInTmp).common).toEqual('/tmp');
expect(commonPath(filesInHome).common).toEqual('/home');
expect(commonPath(allFiles).common).toEqual('/');
});
it('can properly generate relative paths s.t. common + / + relativePath === path', () => {
const testPaths = (paths) => {
const { common, relativePaths } = commonPath(paths);
for (let i = 0; i < relativePaths.length; i++) {
expect(relativePaths[i][0]).not.toEqual('/');
expect(relativePaths[i].length).toBeGreaterThanOrEqual(1);
expect(`${common}/${relativePaths[i]}`.replace(/\/+/g, '/').replace(/(?<=\/)\.$/, '')).toEqual(paths[i]);
}
}
testPaths(filesInTmpTest);
testPaths(filesInTmpHello);
testPaths(filesInTmp);
testPaths(filesInHome);
testPaths(allFiles);
});
})