capture-exit
Advanced tools
Comparing version 1.0.0 to 1.0.1
// remove the next line, and "cleanup" prints. | ||
// | ||
var exit = require('./') | ||
var exit = require('./'); | ||
exit.captureExit(); | ||
@@ -9,5 +9,5 @@ require('ora')('Loading unicorns').start().stop(); | ||
exit.onExit(function() { | ||
console.log('wat') | ||
console.log('wat'); | ||
return new Promise(function(resolve) { | ||
console.log('waiting') | ||
console.log('waiting'); | ||
setTimeout(function() { | ||
@@ -14,0 +14,0 @@ console.log('complete!'); |
19
index.js
@@ -0,8 +1,9 @@ | ||
var RSVP = require('rsvp'); | ||
var exit; | ||
var handlers = []; | ||
var RSVP = require('rsvp'); | ||
var lastTime; | ||
/* | ||
* To allow cooprative async exit handlers, we unfortunately must hijack | ||
* To allow cooperative async exit handlers, we unfortunately must hijack | ||
* process.exit. | ||
@@ -31,9 +32,13 @@ * | ||
process.exit = function(code) { | ||
lastTime = module.exports._flush(lastTime, code) | ||
.finally(function() { | ||
var own = lastTime = module.exports._flush(lastTime, code) | ||
.then(function() { | ||
// if another chain has started, let it exit | ||
if (own !== lastTime) { return; } | ||
exit.call(process, code); | ||
}) | ||
.catch(function(error) { | ||
// if another chain has started, let it exit | ||
if (own !== lastTime) { return; } | ||
console.error(error); | ||
exit.apply(process, 1); | ||
exit.call(process, 1); | ||
}); | ||
@@ -49,5 +54,5 @@ }; | ||
then(function() { | ||
return RSVP.map(work, function(handler) { | ||
return RSVP.Promise.all(work.map(function(handler) { | ||
return handler.call(null, code); | ||
}); | ||
})); | ||
}); | ||
@@ -54,0 +59,0 @@ }; |
{ | ||
"name": "capture-exit", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "safely cleanup in signal handlers", | ||
@@ -22,3 +22,4 @@ "main": "index.js", | ||
"chai": "^3.5.0", | ||
"mocha": "^3.1.2" | ||
"mocha": "^3.1.2", | ||
"ora": "^0.3.0" | ||
}, | ||
@@ -25,0 +26,0 @@ "dependencies": { |
118
test.js
var expect = require('chai').expect; | ||
var exit = require('./'); | ||
var originalExit = process.exit; // keep this around for good measure. | ||
var RSVP = require('rsvp'); | ||
var originalExit = process.exit; // keep this around for good measure. | ||
var exit = require('./'); | ||
describe('capture-exit', function() { | ||
beforeEach(function() { | ||
expect(process.exit, 'ensure we start in a correct state').to.eql(originalExit); | ||
expect(process.exit, 'ensure we start in a correct state').to.equal(originalExit); | ||
}); | ||
afterEach(function() { | ||
// always restore, incase we have bugs in our code while developing | ||
// always restore, in case we have bugs in our code while developing | ||
process.exit = originalExit; | ||
@@ -19,12 +20,12 @@ }); | ||
exit.releaseExit(); | ||
expect(process.exit, 'ensure we remain in a correct state').to.eql(originalExit); | ||
expect(process.exit, 'ensure we remain in a correct state').to.equal(originalExit); | ||
}); | ||
it('does nothing if no exit has yet been captured', function() { | ||
it('restores the original exit', function() { | ||
exit.captureExit(); | ||
expect(process.exit, 'ensure we have captured exit').to.not.eql(originalExit); | ||
expect(process.exit, 'ensure we have captured exit').to.not.equal(originalExit); | ||
exit.releaseExit(); | ||
expect(process.exit, 'ensure we remain in a correct state').to.eql(originalExit); | ||
expect(process.exit, 'ensure we remain in a correct state').to.equal(originalExit); | ||
exit.releaseExit(); | ||
expect(process.exit, 'ensure we still remain in a correct state').to.eql(originalExit); | ||
expect(process.exit, 'ensure we still remain in a correct state').to.equal(originalExit); | ||
}); | ||
@@ -35,4 +36,3 @@ }); | ||
afterEach(function() { | ||
// always restore, incase we have bugs in our code while developing | ||
process.exit = originalExit; | ||
// always restore, in case we have bugs in our code while developing | ||
exit.releaseExit(); | ||
@@ -43,3 +43,3 @@ }); | ||
exit.captureExit(); | ||
expect(process.exit, 'ensure we have replaced').to.not.eql(originalExit); | ||
expect(process.exit, 'ensure we have replaced').to.not.equal(originalExit); | ||
}); | ||
@@ -50,10 +50,10 @@ | ||
exit.captureExit(); | ||
expect(process.exit, 'ensure we have replaced').to.not.eql(originalExit); | ||
expect(process.exit, 'ensure we have replaced').to.not.eql(differentExit); | ||
expect(process.exit, 'ensure we have replaced').to.not.equal(originalExit); | ||
expect(process.exit, 'ensure we have replaced').to.not.equal(differentExit); | ||
exit.releaseExit(); | ||
expect(process.exit, 'we have correctly restored the right exit').to.eql(differentExit); | ||
expect(process.exit, 'we have correctly restored the right exit').to.equal(differentExit); | ||
}); | ||
describe('integration', function() { | ||
it('works', function() { | ||
it('works (simply)', function() { | ||
var exitWasCalled = 0; | ||
@@ -63,3 +63,3 @@ var onExitWasCalled = 0; | ||
exitWasCalled++; | ||
expect(code).to.eql('the expected code'); | ||
expect(code).to.equal('the expected code'); | ||
}; | ||
@@ -77,21 +77,48 @@ | ||
expect(exitWasCalled).to.eql(0); | ||
expect(onExitWasCalled).to.eql(0); | ||
expect(exitWasCalled).to.equal(0); | ||
expect(onExitWasCalled).to.equal(0); | ||
return new RSVP.Promise(function(resolve, reject) { | ||
setTimeout(function() { | ||
try { | ||
deferred.resolve(); | ||
return delay(100).then(function() { | ||
deferred.resolve(); | ||
resolve(deferred.promise.then(function() { | ||
expect(onExitWasCalled).to.eql(1); | ||
})); | ||
} catch(e) { | ||
reject(e); | ||
} | ||
}, 100); | ||
return deferred.promise.then(function() { | ||
expect(onExitWasCalled).to.equal(1); | ||
}); | ||
}).finally(function() { | ||
expect(onExitWasCalled).to.eql(1); | ||
expect(onExitWasCalled).to.equal(1); | ||
}); | ||
}); | ||
it('works (multiple exists)', function() { | ||
var exitWasCalled = 0; | ||
var onExitWasCalled = 0; | ||
process.exit = function stubExit(code) { | ||
exitWasCalled++; | ||
expect(code).to.equal('the expected code'); | ||
}; | ||
var deferred; | ||
exit.captureExit(); | ||
exit.onExit(function() { | ||
onExitWasCalled++; | ||
deferred = RSVP.defer(); | ||
return deferred.promise; | ||
}); | ||
process.exit('NOT the expected code'); | ||
process.exit('the expected code'); | ||
expect(exitWasCalled).to.equal(0); | ||
expect(onExitWasCalled).to.equal(0); | ||
return delay(100).then(function() { | ||
deferred.resolve(); | ||
return deferred.promise.then(function() { | ||
expect(onExitWasCalled).to.equal(1); | ||
}); | ||
}).finally(function() { | ||
expect(onExitWasCalled).to.equal(1); | ||
}); | ||
}); | ||
}); | ||
@@ -106,11 +133,12 @@ }); | ||
} | ||
exit.onExit(foo) | ||
exit.onExit(foo); | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(1); | ||
expect(didExit).to.equal(1); | ||
didExit = 0; | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(0); | ||
expect(didExit).to.equal(0); | ||
}); | ||
}); | ||
}); | ||
it('does not subscribe duplicates', function() { | ||
@@ -124,6 +152,6 @@ var didExit = 0; | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(1); | ||
expect(didExit).to.equal(1); | ||
didExit = 0; | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(0); | ||
expect(didExit).to.equal(0); | ||
}); | ||
@@ -142,3 +170,3 @@ }); | ||
function bar() { | ||
didExitBar++; | ||
didExitBar++; | ||
} | ||
@@ -150,4 +178,4 @@ exit.onExit(foo); | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(0); | ||
expect(didExitBar).to.eql(1); | ||
expect(didExit).to.equal(0); | ||
expect(didExitBar).to.equal(1); | ||
}); | ||
@@ -163,3 +191,3 @@ }); | ||
function bar() { | ||
didExitBar++; | ||
didExitBar++; | ||
} | ||
@@ -172,4 +200,4 @@ exit.onExit(foo); | ||
return exit._flush().then(function() { | ||
expect(didExit).to.eql(0); | ||
expect(didExitBar).to.eql(1); | ||
expect(didExit).to.equal(0); | ||
expect(didExitBar).to.equal(1); | ||
}); | ||
@@ -179,1 +207,7 @@ }); | ||
}); | ||
function delay(milliseconds) { | ||
return new RSVP.Promise(function(resolve) { | ||
setTimeout(resolve, milliseconds); | ||
}); | ||
} |
10304
256
3