Skip to content

Commit

Permalink
Fix: Ensures end event is emitted when input source is empty.
Browse files Browse the repository at this point in the history
  • Loading branch information
nspragg committed Dec 31, 2017
1 parent 3ca504f commit 647e014
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 32 deletions.
13 changes: 13 additions & 0 deletions src/bind.js
@@ -0,0 +1,13 @@
function isMethod(propertyName, value) {
return propertyName !== 'constructor' && typeof value === 'function';
}

module.exports = (obj) => {
const propertyNames = Object.getOwnPropertyNames(obj.constructor.prototype);
propertyNames.forEach((propertyName) => {
const value = obj[propertyName];
if (isMethod(propertyName, value)) {
obj[propertyName] = value.bind(obj);
}
});
};
67 changes: 37 additions & 30 deletions src/filesniffer.js
@@ -1,16 +1,15 @@
import _ from 'lodash';
import bluebird from 'bluebird';
import Promise from 'bluebird';
import fs from 'fs';
import FileHound from 'filehound';
import {
EventEmitter
} from 'events';
import { EventEmitter } from 'events';
import byline from 'byline';
import path from 'path';
import isBinaryFile from './binary';
import zlib from 'zlib';
import isBinaryFile from './binary';
import bind from './bind';

const LineStream = require('byline').LineStream;
const LineStream = byline.LineStream;

function stringMatch(data, string) {
return data.indexOf(string) !== -1;
Expand Down Expand Up @@ -60,18 +59,15 @@ class FileSniffer extends EventEmitter {
this.inputSource = getSource(args);
this.filenames = [];
this.pending = 0;
this.processed = 0;
this.gzipMode = false;
bind(this);
}

_createStream(file) {
if (this._handleGzip(file)) {
const fstream = fs.createReadStream(file);
const unzipStream = zlib.createGunzip();
const lineStream = new LineStream();

fstream
.pipe(unzipStream)
fs.createReadStream(file)
.pipe(zlib.createGunzip())
.pipe(lineStream);

return lineStream;
Expand All @@ -90,9 +86,8 @@ class FileSniffer extends EventEmitter {
return path.extname(file) === '.gz' && this.gzipMode;
}

_notBinaryFile(file) {
_nonBinaryFiles(file) {
if (this._handleGzip(file)) return true;

return !isBinaryFile(file);
}

Expand All @@ -119,8 +114,8 @@ class FileSniffer extends EventEmitter {

if (_.isArray(this.inputSource)) {
const fileTypes = this._groupByFileType(this.inputSource);
const allFiles = bluebird.resolve(fileTypes.files);
let allDirs = bluebird.resolve([]);
const allFiles = Promise.resolve(fileTypes.files);
let allDirs = Promise.resolve([]);

if (fileTypes.dirs.length > 0) {
allDirs = FileHound
Expand All @@ -131,11 +126,25 @@ class FileSniffer extends EventEmitter {
.find();
}

return bluebird.join(allFiles, allDirs, flatten);
return Promise.join(allFiles, allDirs, flatten);
}
}

_search(file, pattern) {
_search(pattern) {
return (files) => {
this.pending = files.length;
if (this.pending > 0) {
Promise.resolve(files).each((file) => {
this._searchFile(file, pattern);
});
}
else {
this._emitEnd();
}
};
}

_searchFile(file, pattern) {
const snifferStream = this._createStream(file);
const isMatch = this._createMatcher(pattern);

Expand All @@ -157,29 +166,27 @@ class FileSniffer extends EventEmitter {
this.pending--;
this.emit('eof', file);
if (matched) this.filenames.push(file);
if (this.pending === 0) {
this.emit('end', this.filenames);
}
this._emitEnd();
});
}

_emitEnd() {
if (this.pending === 0) {
this.emit('end', this.filenames);
}
}

gzip() {
this.gzipMode = true;
return this;
}

find(pattern) {
const notBinaryFile = this._notBinaryFile.bind(this);
const nonBinaryFiles = this._nonBinaryFiles.bind(this);

this._getFiles()
.filter(notBinaryFile)
.then((files) => {
this.pending = files.length;
return files;
})
.each((file) => {
this._search(file, pattern);
});
.filter(nonBinaryFiles)
.then(this._search(pattern));
}

static create() {
Expand Down
20 changes: 18 additions & 2 deletions test/filesniffer.js
Expand Up @@ -22,9 +22,11 @@ function qualifyNames(names) {
return names.map(getAbsolutePath);
}

function mockMatchEvent(sniffer) {
function mockMatchEvent(sniffer, event) {
event = event || 'match';

const spy = sinon.spy();
sniffer.on('match', spy);
sniffer.on(event, spy);

return spy;
}
Expand Down Expand Up @@ -89,6 +91,20 @@ describe('FileSniffer', () => {
sniffer.find(/^f/i);
});

it('emits an end event when given an empty array', (done) => {
const expected = [];

const sniffer = FileSniffer.create([]);
const spy = mockMatchEvent(sniffer, 'end');

sniffer.on('end', () => {
sinon.assert.callCount(spy, 1);
sinon.assert.calledWithMatch(spy, expected);
done();
});
sniffer.find(/^whatever/i);
});

it('throws an error when given an invalid input source', () => {
assert.throws(() => {
FileSniffer.create({});
Expand Down

0 comments on commit 647e014

Please sign in to comment.