find-node-modules
Version:
Return an array of all parent node_modules directories
175 lines (148 loc) • 4.6 kB
JavaScript
var Stream = require('stream');
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var json = typeof JSON === 'object' ? JSON : require('jsonify');
var through = require('through');
var resumer = require('resumer');
var nextTick = typeof setImmediate !== 'undefined'
? setImmediate
: process.nextTick
;
module.exports = Results;
inherits(Results, EventEmitter);
function Results () {
if (!(this instanceof Results)) return new Results;
this.count = 0;
this.fail = 0;
this.pass = 0;
this._stream = through();
this.tests = [];
}
Results.prototype.createStream = function () {
var self = this;
var output = resumer();
output.queue('TAP version 13\n');
nextTick(function () {
var t = getNextTest(self);
if (t) t.run()
else self.emit('done')
});
self._stream.pipe(output);
return output;
};
Results.prototype.push = function (t) {
var self = this;
self.tests.push(t);
self._watch(t);
t.once('end', function () {
var nt = getNextTest(self);
if (nt) nt.run()
else self.emit('done')
});
};
Results.prototype.only = function (name) {
if (this._only) {
self.count ++;
self.fail ++;
write('not ok ' + self.count + ' already called .only()\n');
}
this._only = name;
};
Results.prototype._watch = function (t) {
var self = this;
var write = function (s) { self._stream.queue(s) };
t.once('prerun', function () {
write('# ' + t.name + '\n');
});
t.on('result', function (res) {
if (typeof res === 'string') {
write('# ' + res + '\n');
return;
}
write(encodeResult(res, self.count + 1));
self.count ++;
if (res.ok) self.pass ++
else self.fail ++
});
t.on('test', function (st) { self._watch(st) });
};
Results.prototype.close = function () {
var self = this;
if (self.closed) self._stream.emit('error', new Error('ALREADY CLOSED'));
self.closed = true;
var write = function (s) { self._stream.queue(s) };
write('\n1..' + self.count + '\n');
write('# tests ' + self.count + '\n');
write('# pass ' + self.pass + '\n');
if (self.fail) write('# fail ' + self.fail + '\n')
else write('\n# ok\n')
self._stream.queue(null);
};
function encodeResult (res, count) {
var output = '';
output += (res.ok ? 'ok ' : 'not ok ') + count;
output += res.name ? ' ' + res.name.toString().replace(/\s+/g, ' ') : '';
if (res.skip) output += ' # SKIP';
else if (res.todo) output += ' # TODO';
output += '\n';
if (res.ok) return output;
var outer = ' ';
var inner = outer + ' ';
output += outer + '---\n';
output += inner + 'operator: ' + res.operator + '\n';
var ex = json.stringify(res.expected, getSerialize()) || '';
var ac = json.stringify(res.actual, getSerialize()) || '';
if (Math.max(ex.length, ac.length) > 65) {
output += inner + 'expected:\n' + inner + ' ' + ex + '\n';
output += inner + 'actual:\n' + inner + ' ' + ac + '\n';
}
else {
output += inner + 'expected: ' + ex + '\n';
output += inner + 'actual: ' + ac + '\n';
}
if (res.at) {
output += inner + 'at: ' + res.at + '\n';
}
if (res.operator === 'error' && res.actual && res.actual.stack) {
var lines = String(res.actual.stack).split('\n');
output += inner + 'stack:\n';
output += inner + ' ' + lines[0] + '\n';
for (var i = 1; i < lines.length; i++) {
output += inner + lines[i] + '\n';
}
}
output += outer + '...\n';
return output;
}
function getSerialize () {
var seen = [];
return function (key, value) {
var ret = value;
if (typeof value === 'object' && value) {
var found = false;
for (var i = 0; i < seen.length; i++) {
if (seen[i] === value) {
found = true
break;
}
}
if (found) ret = '[Circular]'
else seen.push(value)
}
return ret;
};
}
function getNextTest(results) {
if (!results._only) {
return results.tests.shift();
}
do {
var t = results.tests.shift();
if (!t) {
return null;
}
if (results._only === t.name) {
return t;
}
} while (results.tests.length !== 0)
}