Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ If the return value is `false`, processing will stop and any remaining results w
- **limit** - *(number)* limits the results read and parsed from the netstat process. Nothingness means no limit.
- **filter** - *(object)* a hash of value conditions for parsed line objects. If a key/value doesn't correspond with one(s) on a parsed object, `handler` won't get called.
- **watch** - *(boolean)* repeatedly run until processing is cancelled by the line handler or by the external handler.
- **processOptions** - *(object)* https://nodejs.org/api/child_process.html#child_processspawnsynccommand-args-options.


### `object netstat.commands`
Expand Down
40 changes: 21 additions & 19 deletions lib/activators.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ var parseLines = require('./utils').parseLines;
exports._spawnSync = spawnSync;
exports._spawn = spawn;

exports.sync = function (cmd, args, makeLineHandler, done) {
exports.sync = function (cmd, args, activatorArgs, makeLineHandler, done) {
var processing = true;
var lineHandler = makeLineHandler(function () {
processing = false;
});

var proc = exports._spawnSync(cmd, args);
var proc = exports._spawnSync(cmd, args, activatorArgs);
if (proc.error) {
return done(proc.error);
}
Expand All @@ -27,9 +26,9 @@ exports.sync = function (cmd, args, makeLineHandler, done) {
return done(null);
};

exports.async = function (cmd, args, makeLineHandler, done) {
exports.async = function (cmd, args, activatorArgs, makeLineHandler, done) {
var killed = false;
var proc = exports._spawn(cmd, args);
var proc = exports._spawn(cmd, args, activatorArgs);

var lineHandler = makeLineHandler(function () {
if (!killed) {
Expand All @@ -50,21 +49,23 @@ exports.async = function (cmd, args, makeLineHandler, done) {
proc.on('close', function () {
done(null);
});

proc.stdout.on('line', lineHandler);
return { cancel:
function() {
if (!killed) {
proc.kill();
killed = true;
return {
cancel:
function () {
if (!killed) {
proc.kill();
killed = true;
}
}
}
};
};

exports.continuous = function (activator, activatorOptions, options) {
var cmd = activatorOptions.cmd;
var args = activatorOptions.args;
var activatorArgs = activatorOptions.activatorArgs;
var makeLineHandler = activatorOptions.makeLineHandler;
var done = activatorOptions.done;
var sync = options.sync;
Expand All @@ -81,7 +82,7 @@ exports.continuous = function (activator, activatorOptions, options) {
};

function runActivator() {
canceller = activator(cmd, args, makeInterceptHandler, function (err) {
canceller = activator(cmd, args, activatorArgs, makeInterceptHandler, function (err) {
if (err) {
completed = true;
return done(err);
Expand All @@ -96,15 +97,16 @@ exports.continuous = function (activator, activatorOptions, options) {

if (!sync) {
runActivator();
return { cancel:
function() {
completed = true;
canceller.cancel();
}
return {
cancel:
function () {
completed = true;
canceller.cancel();
}
};
}

do {
runActivator();
} while(!completed);
} while (!completed);
};
6 changes: 4 additions & 2 deletions lib/netstat.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = function (options, callback) {
var parser = parsers[platform];
var handler = callback;
var activator = options.sync ? activators.sync : activators.async;
var activatorArgs = options.processOptions || undefined;

var makeLineHandler = function (stopParsing) {
return function (line) {
Expand All @@ -58,11 +59,12 @@ module.exports = function (options, callback) {
cmd: command.cmd,
args: command.args,
makeLineHandler: makeLineHandler,
done: done
done: done,
activatorArgs: activatorArgs,
}, { sync: options.sync });

} else {
return activator(command.cmd, command.args, makeLineHandler, done);
return activator(command.cmd, command.args, activatorArgs, makeLineHandler, done);
}
};

Expand Down
170 changes: 107 additions & 63 deletions test/activators.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
var chai = require('chai');
var chai = require("chai");
var expect = chai.expect;
var sinon = require('sinon');
var sinon = require("sinon");
chai.use(require("sinon-chai"));
var EventEmitter = require('events').EventEmitter;
var EventEmitter = require("events").EventEmitter;

var activators = require('../lib/activators');
var utils = require('../lib/utils');
var activators = require("../lib/activators");
var utils = require("../lib/utils");

var data = require('./data');
var data2 = require('./data2');
var testData = data.join('\n');
var testData2 = data2.join('\n');
var data = require("./data");
var data2 = require("./data2");
var testData = data.join("\n");
var testData2 = data2.join("\n");

var makeLineHandler = function (stopHandler) {
return function (line) {
Expand All @@ -26,7 +26,7 @@ function stubProc() {
p.killed = false;
p.kill = function () {
p.killed = true;
p.emit('close');
p.emit("close");
};

return p;
Expand All @@ -36,16 +36,17 @@ function resetSpawnStub() {
proc = stubProc();
proc2 = stubProc();

var stub = sinon.stub(activators, '_spawn');
var stub = sinon.stub(activators, "_spawn");
stub.onCall(0).returns(proc);
stub.onCall(1).returns(proc2);
}

var lineHandler = null;
var proc = null, proc2 = null;
var proc = null,
proc2 = null;

describe('Activators', function () {
describe('asynchronous', function () {
describe("Activators", function () {
describe("asynchronous", function () {
beforeEach(function () {
lineHandler = null;
resetSpawnStub();
Expand All @@ -55,128 +56,171 @@ describe('Activators', function () {
activators._spawn.restore();
});

it('should call the line handler for each line present in the child processes stdout', function (done) {
it("should call the line handler for each line present in the child processes stdout", function (done) {
lineHandler = sinon.spy();

activators.async('', '', makeLineHandler, function () {
expect(lineHandler).to.have.callCount(data.length);
done();
}, false);

proc.stdout.emit('data', testData);
proc.stdout.emit('end');
proc.emit('close');
activators.async(
"",
"",
undefined,
makeLineHandler,
function () {
expect(lineHandler).to.have.callCount(data.length);
done();
},
false
);

proc.stdout.emit("data", testData);
proc.stdout.emit("end");
proc.emit("close");
});

it('should call done when processing is complete', function (done) {
it("should call done when processing is complete", function (done) {
lineHandler = sinon.spy();

activators.async('', '', makeLineHandler, done, false);
activators.async("", "", undefined, makeLineHandler, done, false);

proc.stdout.emit('data', testData);
proc.stdout.emit('end');
proc.emit('close');
proc.stdout.emit("data", testData);
proc.stdout.emit("end");
proc.emit("close");
});

it('should return an error if the child process encounters one', function (done) {
var error = new Error('test error');

activators.async('', '', makeLineHandler, function (err) {
expect(err).to.equal(error);
done();
}, false);

proc.emit('error', error);
it("should return an error if the child process encounters one", function (done) {
var error = new Error("test error");

activators.async(
"",
"",
undefined,
makeLineHandler,
function (err) {
expect(err).to.equal(error);
done();
},
false
);

proc.emit("error", error);
});

it('should call done when canceled', function (done) {
var handler = activators.async('', '', makeLineHandler, done);
it("should call done when canceled", function (done) {
var handler = activators.async(
"",
"",
undefined,
makeLineHandler,
done
);
handler.cancel();
});

it('should take no effect when handler.cancel is called twice', function () {
it("should take no effect when handler.cancel is called twice", function () {
var watchDone = sinon.spy();
var handler = activators.async('', '', makeLineHandler, watchDone);
var handler = activators.async(
"",
"",
undefined,
makeLineHandler,
watchDone
);
handler.cancel();
handler.cancel();
expect(watchDone).to.have.callCount(1);
});
});

describe('synchronous', function () {
describe("synchronous", function () {
beforeEach(function () {
lineHandler = null;
proc = {
error: null,
stdout: testData
stdout: testData,
};

sinon.stub(activators, '_spawnSync').returns(proc);
sinon.stub(activators, "_spawnSync").returns(proc);
});

afterEach(function () {
activators._spawnSync.restore();
});

it('should call the line handler for each line present in the child processes stdout', function () {
it("should call the line handler for each line present in the child processes stdout", function () {
lineHandler = sinon.spy();

activators.sync('', '', makeLineHandler, function () {});
activators.sync("", "", undefined, makeLineHandler, function () {});

expect(lineHandler).to.have.callCount(data.length);
});

it('should call done when processing is complete', function () {
it("should call done when processing is complete", function () {
lineHandler = sinon.spy();
var done = sinon.spy();

activators.sync('', '', makeLineHandler, done);
activators.sync("", "", undefined, makeLineHandler, done);

expect(lineHandler).to.have.callCount(data.length);
expect(done).to.have.been.called;
});

it('should return an error if the child process encounters one', function () {
proc.error = new Error('test error');
it("should return an error if the child process encounters one", function () {
proc.error = new Error("test error");
var done = sinon.spy();

activators.sync('', '', makeLineHandler, done);
activators.sync("", "", undefined, makeLineHandler, done);

expect(done).to.have.been.calledWith(proc.error);
});
});

describe('continuous', function () {
describe("continuous", function () {
var activator = null;

beforeEach(function () {
lineHandler = null;
activator = function (cmd, args, makeLineHandler, done) {
activator = function (cmd, args, undefined, makeLineHandler, done) {
var handler = makeLineHandler(function () {});
handler();
done();
};
});

it('should make repeated async activator calls until processing is stopped', function (done) {
it("should make repeated async activator calls until processing is stopped", function (done) {
lineHandler = sinon.stub();
lineHandler.onCall(3).returns(false);

activators.continuous(activator, { cmd: '', args: '', makeLineHandler, done: function () {
// sinon's onCall() is 0-based index, so call 3 = 4
expect(lineHandler).to.have.callCount(4);

done();
} }, { sync: false });
activators.continuous(
activator,
{
cmd: "",
args: "",
makeLineHandler,
done: function () {
// sinon's onCall() is 0-based index, so call 3 = 4
expect(lineHandler).to.have.callCount(4);

done();
},
},
{ sync: false }
);
});


it('should make repeated sync activator calls until processing is stopped', function () {
it("should make repeated sync activator calls until processing is stopped", function () {
lineHandler = sinon.stub();
lineHandler.onCall(3).returns(false);
var doneSpy = sinon.spy();

activators.continuous(activator, { cmd: '', args: '', makeLineHandler, done: doneSpy }, { sync: true });
activators.continuous(
activator,
{
cmd: "",
args: "",
makeLineHandler,
done: doneSpy,
},
{ sync: true }
);
expect(doneSpy).to.have.callCount(1);
expect(lineHandler).to.have.callCount(4);
});
Expand Down
Loading