Comparing version 0.3.0 to 0.4.0
0.4.0 / 2013-04-06 | ||
================== | ||
* no longer guaranteed compatibility with node 0.4x | ||
0.3.0 / 2013-04-06 | ||
@@ -3,0 +8,0 @@ ================== |
@@ -5,3 +5,3 @@ { | ||
"description": "Node global variable leak detector", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"repository": { | ||
@@ -16,3 +16,3 @@ "type": "git" | ||
"engines": { | ||
"node": ">=0.4.1" | ||
"node": ">=0.6" | ||
}, | ||
@@ -22,4 +22,3 @@ "dependencies": {}, | ||
"express": ">=2.0.0" | ||
, "mocha": "*" | ||
} | ||
} |
@@ -91,7 +91,9 @@ # Gleak | ||
npm install gleak | ||
npm install gleak | ||
### Node version | ||
Compatible with Node >=v0.4 <0.5.0 | ||
Compatible with Node >=0.6 | ||
Node >= 0.4.1 probably still works too but the tests no longer confirm it. | ||
## License | ||
@@ -98,0 +100,0 @@ |
@@ -0,242 +1,107 @@ | ||
var mod = require('./tests') | ||
var tests = Object.keys(mod); | ||
var total = tests.length; | ||
var failed = []; | ||
var assert = require('assert') | ||
var gleak = require('../index') | ||
var request = require('./_request') | ||
var express; | ||
;(function run () { | ||
var desc = tests.shift(); | ||
if (!desc) return report(); | ||
var fn = mod[desc]; | ||
runTest(desc, fn, run); | ||
})() | ||
// node 4 tests? | ||
var v = process.version.replace(/^v/,'').split('.'); | ||
if ('0' == v[0] && v[1] > 4) | ||
express = require('express') | ||
exports['version exists'] = function () { | ||
assert.equal('string', typeof gleak.version); | ||
function runTest (desc, test, done) { | ||
function complete () { | ||
if (complete.ran) { | ||
failed.push([desc, new Error('done called more than once')]) | ||
return; | ||
} | ||
complete.ran = true; | ||
done(); | ||
} | ||
if (test.length) { | ||
runTestAsync(desc, test, complete); | ||
} else { | ||
runTestSync(desc, test); | ||
process.nextTick(complete); | ||
} | ||
} | ||
exports['middleware exists'] = function () { | ||
assert.equal('function', typeof gleak.middleware); | ||
} | ||
function runTestAsync (desc, test, done) { | ||
var start = new Date; | ||
var e; | ||
exports['gleak is a function'] = function () { | ||
assert.equal('function', typeof gleak); | ||
} | ||
function handleError (err) { | ||
failed.push([desc, e = err]); | ||
fail(desc, start); | ||
} | ||
exports['default format is correct'] = function () { | ||
var g = gleak(); | ||
assert.equal('\x1b[31mGleak!:\x1b[0m %s', g.format); | ||
} | ||
function handleUncaught (err) { | ||
handleError(err); | ||
complete(); | ||
} | ||
exports['whitelist is an array'] = function () { | ||
var g = gleak(); | ||
assert.ok(Array.isArray(g.whitelist)); | ||
} | ||
function complete () { | ||
process.removeListener('uncaughtException', handleUncaught); | ||
done(); | ||
} | ||
exports['setTimeout is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(setTimeout)); | ||
}; | ||
process.on('uncaughtException', handleUncaught); | ||
exports['setInterval is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(setInterval)); | ||
}; | ||
exports['clearTimeout is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(clearTimeout)); | ||
}; | ||
exports['clearInterval is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(clearInterval)); | ||
}; | ||
exports['console is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(console)); | ||
}; | ||
exports['Buffer is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(Buffer)); | ||
}; | ||
exports['process is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(process)); | ||
}; | ||
exports['global is a default'] = function () { | ||
var g = gleak(); | ||
assert.ok(~g.whitelist.indexOf(global)); | ||
}; | ||
exports['whitelist is mutable'] = function () { | ||
var g = gleak(); | ||
var i = g.whitelist.push(assert); | ||
assert.ok(~g.whitelist.indexOf(assert)); | ||
g.whitelist.splice(i-1, 1); | ||
assert.ok(!~g.whitelist.indexOf(assert)); | ||
try { | ||
test(function (err) { | ||
if (e) return; | ||
if (err) { | ||
handleError(err); | ||
complete(); | ||
return; | ||
} | ||
pass(desc, start); | ||
complete(); | ||
}); | ||
} catch (err) { | ||
handleError(err); | ||
process.nextTick(complete) | ||
} | ||
} | ||
exports['#detect is a function'] = function () { | ||
var g = gleak(); | ||
assert.ok('function' === typeof g.detect); | ||
function fail (desc, start) { | ||
console.log('\x1b[31mx ' + desc + ':\x1b[30m ' + (Date.now() - start) + 'ms\x1b[0m'); | ||
} | ||
exports['detect()'] = function () { | ||
var g = gleak(); | ||
var found = g.detect(); | ||
assert.ok(Array.isArray(found)); | ||
assert.ok(0 === found.length); | ||
haha = "lol" | ||
assert.equal(1, g.detect().length); | ||
assert.equal("haha", g.detect()[0]); | ||
function pass (desc, start) { | ||
console.log('\x1b[32m√\x1b[30m ' + desc + ': ' + (Date.now() - start) + 'ms\x1b[0m'); | ||
} | ||
exports['unknown values can be whitelisted by passing strings'] = function () { | ||
var g = gleak(); | ||
ignoreme = 1; | ||
assert.ok(~g.detect().indexOf('ignoreme')); | ||
g.whitelist.push('ignoreme'); | ||
assert.ok(!~g.detect().indexOf('ignoreme')); | ||
delete global.ignoreme; | ||
} | ||
function runTestSync (desc, test) { | ||
var start = new Date; | ||
var e; | ||
exports['#ignore'] = function () { | ||
var g = gleak(); | ||
assert.equal('function', typeof g.ignore); | ||
} | ||
exports['ignore identical whitelisted values'] = function () { | ||
var g = gleak(); | ||
var len = g.whitelist.length; | ||
var an = 'another'; | ||
g.ignore('another', 'another', 'another', an); | ||
assert.equal(len + 1, g.whitelist.length); | ||
} | ||
exports['#print'] = function () { | ||
var g = gleak(); | ||
var write = console.error; | ||
var times = 0; | ||
haha = "heh"; | ||
console.error = function (format, item) { | ||
assert.equal(g.format, format); | ||
assert.equal("haha", item); | ||
++times; | ||
try { | ||
test(); | ||
} catch (err) { | ||
failed.push([desc, err]); | ||
fail(desc, start); | ||
return; | ||
} | ||
g.print(); | ||
console.error = write; | ||
assert.equal(1, times); | ||
} | ||
exports['whitelists are seperate from other instances'] = function () { | ||
var g1 = gleak() | ||
, g2 = gleak(); | ||
g1.ignore('the', 'bad'); | ||
assert.ok(~g1.whitelist.indexOf('the')); | ||
assert.ok(!~g2.whitelist.indexOf('the')); | ||
pass(desc, start); | ||
} | ||
exports['formats are seperate from other instances'] = function () { | ||
var g1 = gleak() | ||
, g2 = gleak(); | ||
function report () { | ||
console.log(); | ||
g1.format = "different %s"; | ||
assert.ok(~g1.format !== g1.format); | ||
} | ||
if (!failed.length) { | ||
console.log('\x1b[32m%d tests complete\x1b[0m', total); | ||
} else { | ||
console.log('\x1b[31m%d failed\x1b[0m', failed.length); | ||
console.error(); | ||
exports['#detectNew'] = function () { | ||
var g = gleak(); | ||
assert.equal('function', typeof g.detectNew); | ||
var found = g.detectNew(); | ||
assert.equal(true, Array.isArray(found)); | ||
assert.equal(found.length, 1); | ||
assert.equal(g.detectNew().length, 0); | ||
zombocom = 'welcome'; | ||
found = g.detectNew(); | ||
assert.equal(found.length, 1); | ||
assert.equal(found[0], 'zombocom'); | ||
assert.equal(g.detectNew().length, 0); | ||
delete global.zombocom; | ||
} | ||
exports['test middleware'] = function (done) { | ||
if ('0' == v[0] && v[1] < 5) return done(); | ||
var called = false; | ||
var req = {}; | ||
var res = { send: function (x) { assert.equal(x, 'yes'); called = true; }}; | ||
var m = gleak.middleware(); | ||
m(req, res, function(){}); | ||
assert.equal(res._gleak, true); | ||
res.send('yes'); | ||
assert.equal(true, called); | ||
// another leak | ||
meToo = 47; | ||
// mock stream | ||
function makeStream (tests) { | ||
return { | ||
i: 0 | ||
, write: function (data) { | ||
assert.equal(tests[this.i], data); | ||
++this.i; | ||
} | ||
} | ||
failed.forEach(function (failure, i) { | ||
console.error((i+1) + ') ' + failure[0], failure[1].stack); | ||
console.error(); | ||
}) | ||
} | ||
var express3 = express.version.split('.')[0] > 2; | ||
var app = express3 | ||
? express() | ||
: express.createServer(); | ||
var sout = [ | ||
'\x1b[31mGleak!:\x1b[0m haha\n' | ||
, '\x1b[31mGleak!:\x1b[0m meToo\n' | ||
]; | ||
var stream1 = makeStream(sout); | ||
app.get('/stream', gleak.middleware(stream1), function (req, res, next) { | ||
res.send('passed a stream'); | ||
}); | ||
var both = [ | ||
'yes : haha\n' | ||
, 'yes : meToo\n' | ||
]; | ||
var stream2 = makeStream(both); | ||
app.get('/formatstream', gleak.middleware(stream2, 'yes : %s'), function (req, res, next) { | ||
res.send('passed format and stream'); | ||
}); | ||
var pending = 2; | ||
var svr = app.listen(0, function () { | ||
request.address = svr.address(); | ||
ready(); | ||
}); | ||
function ready () { | ||
request() | ||
.get('/stream') | ||
.end(function (res) { | ||
assert.equal(200, res.statusCode); | ||
assert.equal('passed a stream', res.body); | ||
assert.equal(2, stream1.i); | ||
finish(); | ||
}); | ||
request() | ||
.get('/formatstream') | ||
.end(function (res) { | ||
assert.equal(200, res.statusCode); | ||
assert.equal('passed format and stream', res.body); | ||
assert.equal(stream2.i, 2); | ||
finish(); | ||
}); | ||
} | ||
function finish () { | ||
if (--pending) return; | ||
done(); | ||
} | ||
process.exit(failed.length); | ||
} | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
19116
1
10
538
122