From e6920de47772d4e81ceef665fc562cd5151a832d Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Thu, 17 May 2018 17:58:26 +0300 Subject: [PATCH 1/3] Initial tests. --- karma.conf.js | 13 ++++++ package.json | 11 ++++- src/main.js | 21 ++++++--- test/engine-init.js | 106 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 karma.conf.js create mode 100644 test/engine-init.js diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..821cdad --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,13 @@ +module.exports = function(config) { + config.set({ + frameworks: [ + 'mocha' + ], + plugins: [ + 'karma-mocha' + ], + files: [ + 'test/*.js' + ] + }); +}; diff --git a/package.json b/package.json index 780773f..126f594 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,19 @@ }, "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=4.0" }, "devDependencies": { + "chai": "^4.1.2", + "chai-as-promised": "^7.1.1", "grunt": "^0.4.5", "grunt-cafe-mocha": "^0.1.13", "grunt-contrib-jshint": "^1.1.0", - "grunt-groc": "^0.7.1" + "grunt-groc": "^0.7.1", + "mocha": "^5.1.1", + "mock-spawn": "^0.2.6" + }, + "scripts": { + "test": "mocha" } } diff --git a/src/main.js b/src/main.js index 45446bd..b996a4c 100644 --- a/src/main.js +++ b/src/main.js @@ -24,20 +24,29 @@ util.inherits(Engine, events.EventEmitter); Engine.prototype.runProcess = function () { var self = this; var deferred = Q.defer(); - this.engineProcess = spawn(this.engineFile); + var numberOfTriesBeforeTimeout = 10; + var currentIntervalNumber = 0 var timer; + + this.engineProcess = spawn(this.engineFile); + this.engineProcess.once('error', function (error) { clearInterval(timer); deferred.reject(error); }); timer = setInterval(function () { + currentIntervalNumber += 1; + if (utilities.isProcessRunning(self.engineProcess)) { clearInterval(timer); deferred.resolve(); + } else if (currentIntervalNumber === numberOfTriesBeforeTimeout) { + clearInterval(timer); + deferred.reject(new Error('timeout while starting process')); } - }, 100); + return deferred.promise; }; @@ -189,7 +198,7 @@ Engine.prototype.timeLimitedGoCommand = function (infoHandler, var self = this; var deferred = Q.defer(); var pendingData = ""; - + var engineStdoutListener = function (data) { var lines = utilities.getLines(pendingData+data); pendingData = lines.incompleteLine ? lines.incompleteLine : ""; @@ -231,7 +240,7 @@ Engine.prototype.timeLimitedGoCommand = function (infoHandler, //called for each info line output by the engine. Engine.prototype.goCommand = function (commands, infoHandler) { var pendingData = ""; - + var engineStdoutListener = function (data) { var lines = utilities.getLines(pendingData+data); pendingData = lines.incompleteLine ? lines.incompleteLine : ""; @@ -280,7 +289,7 @@ Engine.prototype.goCommand = function (commands, infoHandler) { //called for each info line output by the engine. Engine.prototype.goInfiniteCommand = function (infoHandler) { var pendingData = ""; - + var engineStdoutListener = function (data) { var lines = utilities.getLines(pendingData+data); pendingData = lines.incompleteLine ? lines.incompleteLine : ""; @@ -308,7 +317,7 @@ Engine.prototype.stopCommand = function () { var self = this; var deferred = Q.defer(); var pendingData = ""; - + var engineStdoutListener = function (data) { var lines = utilities.getLines(pendingData+data); pendingData = lines.incompleteLine ? lines.incompleteLine : ""; diff --git a/test/engine-init.js b/test/engine-init.js new file mode 100644 index 0000000..d0ab2be --- /dev/null +++ b/test/engine-init.js @@ -0,0 +1,106 @@ +/** + * Setup testing with `chai`. + */ + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); +chai.use(chaiAsPromised); +chai.should(); +var expect = chai.expect; + + + +/** + * Setup `child_process.spawn` mocks. + */ +var mockSpawn = require('mock-spawn'); +var mySpawn = mockSpawn(); +require('child_process').spawn = mySpawn; + +// First spawn -> emit error, exit with status (1). +mySpawn.sequence.add(function (cb) { + this.emit('error', new Error('spawn ' + badEnginePath + ' ENOENT')); + setTimeout(function() { return cb(1); }, 10); +}); +// Second spawn -> slow start of application. Simulate timeout error. +mySpawn.sequence.add(function (cb) { + var self = this; + + setTimeout(function () { + self.stdout.write('some output data'); + + return cb(0); + }, 1500); +}); +// Third spawn -> normal application start. +mySpawn.sequence.add(function (cb) { + var self = this; + + setTimeout(function () { + self.stdout.write('some output data'); + + return cb(0); + }, 100); +}); + + + +/** + * Some predefined constants to be used in tests. + */ + +var badEnginePath = 'non_existent_engine'; +var testEcecutableFile = 'test_executable'; + + + +/** + * Out subject-under-test. + */ + +var Engine = require('../src/main'); + + + +/** + * Now the tests start :) + */ + +describe('Engine', function () { + describe('contructor', function () { + it('throws when no engine path is provided', function () { + return expect(function () { + new Engine(); + }).to.throw('Path must be a string. Received undefined') + }); + + it('does not throw on bad engine path', function () { + return expect(function () { + new Engine('non_existent_engine'); + }).to.not.throw() + }); + }); + + describe('runProcess', function () { + it('throws when tries to launch non existent path', function () { + var engine = new Engine(badEnginePath); + var promise = engine.runProcess(); + + return promise.should.be.rejectedWith('spawn ' + badEnginePath + ' ENOENT'); + }); + + it('throws timeout error if executable does not start within allowed timeout period', function () { + var engine = new Engine(testEcecutableFile); + var promise = engine.runProcess(); + + return promise.should.be.rejectedWith('timeout while starting process'); + }); + + it('does not throw if executable launched OK', function () { + var engine = new Engine(testEcecutableFile); + var promise = engine.runProcess(); + + return promise.should.not.be.rejected; + }); + }); +}); From 16104043885375bda0567c52c537fe0d61423fc4 Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Thu, 17 May 2018 18:01:50 +0300 Subject: [PATCH 2/3] Removing karma.conf.js file. --- karma.conf.js | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 karma.conf.js diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 821cdad..0000000 --- a/karma.conf.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function(config) { - config.set({ - frameworks: [ - 'mocha' - ], - plugins: [ - 'karma-mocha' - ], - files: [ - 'test/*.js' - ] - }); -}; From 1228c6495649088b74d4aafede92247040ce7cb3 Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Thu, 17 May 2018 18:07:11 +0300 Subject: [PATCH 3/3] Fix spelling. --- test/engine-init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/engine-init.js b/test/engine-init.js index d0ab2be..0154a6d 100644 --- a/test/engine-init.js +++ b/test/engine-init.js @@ -55,7 +55,7 @@ var testEcecutableFile = 'test_executable'; /** - * Out subject-under-test. + * Our subject-under-test. */ var Engine = require('../src/main');