Skip to content

Commit

Permalink
Merge pull request #14 from gemini-testing/collections
Browse files Browse the repository at this point in the history
Get rid of q-io
  • Loading branch information
Dmitriy-kiselyov authored Jan 16, 2018
2 parents 8db286c + 93bd35f commit ba20d0d
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 119 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
*.log
coverage
.idea
27 changes: 9 additions & 18 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
'use strict';

const q = require('q');
const qfs = require('q-io/fs');
const Promise = require('bluebird');
const _ = require('lodash');
const glob = require('glob');
const glob = Promise.promisify(require('glob'));
const defaults = require('./defaults');
const utils = require('./utils');
const resolvePath = require('path').resolve;
const path = require('path');

const isMask = (pattern) => glob.hasMagic(pattern);

const getFilesByMask = (pattern, options) => q.nfcall(glob, pattern, options);
const getFilesByMask = (pattern, options) => glob(pattern, options);

const listFiles = (path) => {
return qfs.listTree(path)
.then((paths) => utils.asyncFilter(paths, utils.isFile));
};

const expandPath = (path, options) => {
path = options.root ? resolvePath(options.root, path) : path;
const expandPath = (basePath, options) => {
basePath = options.root ? path.resolve(options.root, basePath) : basePath;

return utils.isFile(path)
.then((isFile) => isFile ? [path] : listFiles(path))
return utils.isFile(basePath)
.then((isFile) => isFile ? [basePath] : utils.getFilePaths(basePath))
.then((paths) => paths.filter((path) => utils.matchesFormats(path, options.formats)));
};

const processPaths = (paths, cb) => {
return _(paths)
.map(cb)
.thru(q.all)
.value()
return Promise.map(paths, cb)
.then(_.flatten)
.then(_.uniq);
};
Expand Down
33 changes: 21 additions & 12 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
'use strict';

const _ = require('lodash');
const q = require('q');
const qfs = require('q-io/fs');
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
const path = require('path');

exports.asyncFilter = (items, cb) => {
return _(items)
.map((item) => cb(item).then((res) => res && item))
.thru(q.all)
.value()
.then(_.compact);
exports.matchesFormats = (filePath, formats) => {
return _.isEmpty(formats) || _.includes(formats, path.extname(filePath));
};

exports.matchesFormats = (path, formats) => {
return _.isEmpty(formats) || _.includes(formats, qfs.extension(path));
};
exports.isFile = (path) => fs.statAsync(path).then((stat) => stat.isFile());

exports.getFilePaths = (basePath) => {
function readDirFiles(basePath) {
return fs.readdirAsync(basePath)
.then((paths) => {
return Promise.map(paths, (p) => exports.getFilePaths(path.join(basePath, p)))
.then(_.flatten);
});
}

exports.isFile = (path) => qfs.stat(path).then((stat) => stat.isFile());
return exports.isFile(basePath)
.then((isFile) => isFile ? [basePath] : readDirFiles(basePath))
.catch((err) => {
throw new Error(`Error while reading path "${basePath}"\n${err.stack || err.message || err}`);
});
};
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/gemini-testing/path-utils.git"
"url": "git://github.com/gemini-testing/glob-extra.git"
},
"keywords": [
"expand",
Expand All @@ -27,8 +27,7 @@
"dependencies": {
"glob": "^7.0.5",
"lodash": "^4.15.0",
"q": "^1.1.2",
"q-io": "^2.0.6"
"bluebird": "^3.5.1"
},
"devDependencies": {
"chai": "^3.4.1",
Expand All @@ -38,6 +37,6 @@
"istanbul": "^0.4.5",
"mocha": "^2.4.5",
"proxyquire": "^1.7.3",
"sinon": "^1.17.2"
"sinon": "^4.1.4"
}
}
48 changes: 11 additions & 37 deletions test/index.test.js → test/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

const proxyquire = require('proxyquire');
const qfs = require('q-io/fs');
const q = require('q');
const fs = require('fs');
const utils = require('../lib/utils');

describe('path-utils', () => {
Expand All @@ -13,21 +12,17 @@ describe('path-utils', () => {

beforeEach(() => {
sandbox.stub(process, 'cwd').returns('');
sandbox.stub(qfs, 'listTree');
sandbox.stub(qfs, 'stat').returns(q({isFile: () => true}));

glob = sandbox.stub();

globExtra = proxyquire('../lib/index', {glob});

sandbox.stub(utils, 'getFilePaths');
sandbox.stub(fs, 'statAsync').resolves({isFile: () => true});
});

afterEach(() => sandbox.restore());

describe('masks', () => {
beforeEach(() => {
sandbox.stub(qfs, 'absolute');
});

it('should get file path from passed mask', () => {
glob.withArgs('some/deep/**/*.js').yields(null, ['some/deep/path/file.js']);

Expand All @@ -39,8 +34,6 @@ describe('path-utils', () => {
glob.withArgs('bad/mask/*.js').yields(null, []);
glob.withArgs('some/path/*.js').yields(null, ['some/path/file.js']);

qfs.absolute.returnsArg(0);

return globExtra.expandPaths([
'bad/mask/*.js',
'some/path/*.js'
Expand Down Expand Up @@ -68,14 +61,13 @@ describe('path-utils', () => {

describe('directories', () => {
beforeEach(() => {
qfs.stat.withArgs('some/path').returns(q({isFile: () => false}));
sandbox.stub(qfs, 'absolute');
fs.statAsync.withArgs('some/path').resolves({isFile: () => false});
});

it('should get paths for all files from passed dir', () => {
glob.withArgs('some/path').yields(null, ['some/path']);

qfs.listTree.withArgs('some/path').returns(q(['some/path/first.js', 'some/path/second.txt']));
utils.getFilePaths.withArgs('some/path').resolves(['some/path/first.js', 'some/path/second.txt']);

return globExtra.expandPaths(['some/path'])
.then((paths) => {
Expand All @@ -86,7 +78,7 @@ describe('path-utils', () => {
it('should get file paths according to formats option', () => {
glob.withArgs('some/path').yields(null, ['some/path']);

qfs.listTree.withArgs('some/path').returns(q(['some/path/first.js', 'some/path/second.txt']));
utils.getFilePaths.withArgs('some/path').resolves(['some/path/first.js', 'some/path/second.txt']);

return globExtra.expandPaths(['some/path'], {formats: ['.js']})
.then((paths) => assert.deepEqual(paths, ['some/path/first.js']));
Expand All @@ -95,32 +87,16 @@ describe('path-utils', () => {
it('should get uniq absolute file path from passed dirs', () => {
glob.withArgs('some/path').yields(null, ['some/path']);

qfs.listTree.withArgs('some/path').returns(q(['some/path/file.js']));
utils.getFilePaths.withArgs('some/path').resolves(['some/path/file.js']);

return globExtra.expandPaths(['some/path', 'some/path'])
.then((paths) => {
assert.deepEqual(paths, ['some/path/file.js']);
});
});

it('should get only file paths from dir tree', () => {
glob.withArgs('some/path').yields(null, ['some/path']);

qfs.stat.withArgs('some/path/dir').returns(q({isFile: () => false}));
qfs.listTree.withArgs('some/path').returns(q(['some/path/file.js', 'some/path/dir']));

return globExtra.expandPaths(['some/path'])
.then((paths) => {
assert.deepEqual(paths, ['some/path/file.js']);
});
});
});

describe('files', () => {
beforeEach(() => {
sandbox.stub(qfs, 'absolute');
});

it('should get file path from passed string file path', () => {
glob.withArgs('some/path/file.js').yields(null, ['some/path/file.js']);

Expand Down Expand Up @@ -164,8 +140,8 @@ describe('path-utils', () => {
it('should use project root passed from root option', () => {
glob.withArgs('some/path/').yields(null, ['some/path/']);

qfs.stat.withArgs('/project/root/some/path').returns(q({isFile: () => false}));
qfs.listTree.withArgs('/project/root/some/path').returns(q(['/project/root/some/path/file.js']));
fs.statAsync.withArgs('/project/root/some/path').resolves({isFile: () => false});
utils.getFilePaths.withArgs('/project/root/some/path').resolves(['/project/root/some/path/file.js']);

return globExtra.expandPaths(['some/path/'], {root: '/project/root'})
.then((paths) => {
Expand All @@ -175,8 +151,6 @@ describe('path-utils', () => {
});

describe('glob options', () => {
beforeEach(() => sandbox.stub(qfs, 'absolute'));

it('should exclude file paths from passed masks', () => {
const globOpts = {ignore: ['some/other/*']};

Expand All @@ -199,7 +173,7 @@ describe('path-utils', () => {
});

describe('project root', () => {
beforeEach(() => sandbox.stub(utils, 'isFile').returns(q(true)));
beforeEach(() => sandbox.stub(utils, 'isFile').resolves(true));

it('shout resolve relative paths using project root', () => {
glob.withArgs('some/path').yields(null, ['some/path/file.js']);
Expand Down
84 changes: 84 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';

const fs = require('fs');
const utils = require('../lib/utils');

describe('utils', () => {
const sandbox = sinon.sandbox.create();

afterEach(() => sandbox.restore());

describe('matchesFormats', () => {
it('should return `true` if the formats option contain passed file format', () => {
assert.isTrue(utils.matchesFormats('some/path/file.js', ['.js']));
});

it('should return `false` if the formats option does not contain passed file format', () => {
assert.isFalse(utils.matchesFormats('some/path/file.js', ['.txt']));
});
});

describe('isFile', () => {
beforeEach(() => {
sandbox.stub(fs, 'statAsync');
});

it('should return `true` if the passed path is file', () => {
fs.statAsync.resolves({isFile: () => true});

return assert.becomes(utils.isFile('some/path/file.js'), true);
});

it('should return `false` if the passed path is directory', () => {
fs.statAsync.resolves({isFile: () => false});

return assert.becomes(utils.isFile('some/path/dir'), false);
});
});

describe('getFilePaths', () => {
const createStatStub = (paths, opts) => {
paths.forEach((path) => {
fs.statAsync.withArgs(path).resolves({isFile: () => opts.isFile});
});
};

const createFiles = (...paths) => createStatStub(paths, {isFile: true});

const createDirs = (...paths) => createStatStub(paths, {isFile: false});

beforeEach(() => {
sandbox.stub(fs, 'statAsync');
sandbox.stub(fs, 'readdirAsync');
});

it('should return file if argument is a file', () => {
createFiles('file.js');

return assert.becomes(utils.getFilePaths('file.js'), ['file.js']);
});

it('should return empty array if argument is an empty directory', () => {
createDirs(false, 'dir');
fs.readdirAsync.withArgs('dir').resolves([]);

return assert.becomes(utils.getFilePaths('dir'), []);
});

it('should return only files from file system', () => {
createDirs('root', 'root/subdir');
createFiles('root/file.js', 'root/subdir/file2.txt', 'root/subdir/file3.txt');
fs.readdirAsync.withArgs('root').resolves(['file.js', 'subdir']);
fs.readdirAsync.withArgs('root/subdir').resolves(['file2.txt', 'file3.txt']);

return assert.becomes(utils.getFilePaths('root'), ['root/file.js', 'root/subdir/file2.txt', 'root/subdir/file3.txt']);
});

it('should throw an error if directory is not acceptable', () => {
createDirs('root');
fs.readdirAsync.rejects('no-rights');

return assert.isRejected(utils.getFilePaths('root'), /no-rights/);
});
});
});
48 changes: 0 additions & 48 deletions test/utils.test.js

This file was deleted.

0 comments on commit ba20d0d

Please sign in to comment.