314 lines
8.9 KiB
JavaScript
314 lines
8.9 KiB
JavaScript
![]() |
var tape = require('../');
|
||
|
var tap = require('tap');
|
||
|
var concat = require('concat-stream');
|
||
|
var tapParser = require('tap-parser');
|
||
|
var yaml = require('js-yaml');
|
||
|
|
||
|
tap.test('preserves stack trace with newlines', function (tt) {
|
||
|
tt.plan(3);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
var stream = test.createStream();
|
||
|
var parser = stream.pipe(tapParser());
|
||
|
var stackTrace = 'foo\n bar';
|
||
|
|
||
|
parser.once('assert', function (data) {
|
||
|
delete data.diag.at;
|
||
|
tt.deepEqual(data, {
|
||
|
ok: false,
|
||
|
id: 1,
|
||
|
name: 'Error: Preserve stack',
|
||
|
diag: {
|
||
|
stack: stackTrace,
|
||
|
operator: 'error',
|
||
|
expected: 'undefined',
|
||
|
actual: '[Error: Preserve stack]'
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
stream.pipe(concat(function (body) {
|
||
|
var body = body.toString('utf8');
|
||
|
body = stripAt(body);
|
||
|
tt.equal(
|
||
|
body,
|
||
|
'TAP version 13\n'
|
||
|
+ '# multiline stack trace\n'
|
||
|
+ 'not ok 1 Error: Preserve stack\n'
|
||
|
+ ' ---\n'
|
||
|
+ ' operator: error\n'
|
||
|
+ ' expected: |-\n'
|
||
|
+ ' undefined\n'
|
||
|
+ ' actual: |-\n'
|
||
|
+ ' [Error: Preserve stack]\n'
|
||
|
+ ' stack: |-\n'
|
||
|
+ ' foo\n'
|
||
|
+ ' bar\n'
|
||
|
+ ' ...\n'
|
||
|
+ '\n'
|
||
|
+ '1..1\n'
|
||
|
+ '# tests 1\n'
|
||
|
+ '# pass 0\n'
|
||
|
+ '# fail 1\n'
|
||
|
);
|
||
|
|
||
|
tt.deepEqual(getDiag(body), {
|
||
|
stack: stackTrace,
|
||
|
operator: 'error',
|
||
|
expected: 'undefined',
|
||
|
actual: '[Error: Preserve stack]'
|
||
|
});
|
||
|
}));
|
||
|
|
||
|
test('multiline stack trace', function (t) {
|
||
|
t.plan(1);
|
||
|
var err = new Error('Preserve stack');
|
||
|
err.stack = stackTrace;
|
||
|
t.error(err);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
tap.test('parses function info from original stack', function (tt) {
|
||
|
tt.plan(4);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
test.createStream();
|
||
|
|
||
|
test._results._watch = function (t) {
|
||
|
t.on('result', function (res) {
|
||
|
tt.equal('Test.testFunctionNameParsing', res.functionName);
|
||
|
tt.match(res.file, /stackTrace.js/i);
|
||
|
tt.ok(Number(res.line) > 0);
|
||
|
tt.ok(Number(res.column) > 0);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
test('t.equal stack trace', function testFunctionNameParsing(t) {
|
||
|
t.equal(true, false, 'true should be false');
|
||
|
t.end();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
tap.test('parses function info from original stack for anonymous function', function (tt) {
|
||
|
tt.plan(4);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
test.createStream();
|
||
|
|
||
|
test._results._watch = function (t) {
|
||
|
t.on('result', function (res) {
|
||
|
tt.equal('Test.<anonymous>', res.functionName);
|
||
|
tt.match(res.file, /stackTrace.js/i);
|
||
|
tt.ok(Number(res.line) > 0);
|
||
|
tt.ok(Number(res.column) > 0);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
test('t.equal stack trace', function (t) {
|
||
|
t.equal(true, false, 'true should be false');
|
||
|
t.end();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
if (typeof Promise === 'function' && typeof Promise.resolve === 'function') {
|
||
|
|
||
|
tap.test('parses function info from original stack for Promise scenario', function (tt) {
|
||
|
tt.plan(4);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
test.createStream();
|
||
|
|
||
|
test._results._watch = function (t) {
|
||
|
t.on('result', function (res) {
|
||
|
tt.equal('onfulfilled', res.functionName);
|
||
|
tt.match(res.file, /stackTrace.js/i);
|
||
|
tt.ok(Number(res.line) > 0);
|
||
|
tt.ok(Number(res.column) > 0);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
test('t.equal stack trace', function testFunctionNameParsing(t) {
|
||
|
new Promise(function (resolve) {
|
||
|
resolve();
|
||
|
}).then(function onfulfilled() {
|
||
|
t.equal(true, false, 'true should be false');
|
||
|
t.end();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
tap.test('parses function info from original stack for Promise scenario with anonymous function', function (tt) {
|
||
|
tt.plan(4);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
test.createStream();
|
||
|
|
||
|
test._results._watch = function (t) {
|
||
|
t.on('result', function (res) {
|
||
|
tt.equal('<anonymous>', res.functionName);
|
||
|
tt.match(res.file, /stackTrace.js/i);
|
||
|
tt.ok(Number(res.line) > 0);
|
||
|
tt.ok(Number(res.column) > 0);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
test('t.equal stack trace', function testFunctionNameParsing(t) {
|
||
|
new Promise(function (resolve) {
|
||
|
resolve();
|
||
|
}).then(function () {
|
||
|
t.equal(true, false, 'true should be false');
|
||
|
t.end();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
}
|
||
|
|
||
|
tap.test('preserves stack trace for failed assertions', function (tt) {
|
||
|
tt.plan(6);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
var stream = test.createStream();
|
||
|
var parser = stream.pipe(tapParser());
|
||
|
|
||
|
var stack = '';
|
||
|
parser.once('assert', function (data) {
|
||
|
tt.equal(typeof data.diag.at, 'string');
|
||
|
tt.equal(typeof data.diag.stack, 'string');
|
||
|
at = data.diag.at || '';
|
||
|
stack = data.diag.stack || '';
|
||
|
tt.ok(/^Error: true should be false(\n at .+)+/.exec(stack), 'stack should be a stack');
|
||
|
tt.deepEqual(data, {
|
||
|
ok: false,
|
||
|
id: 1,
|
||
|
name: 'true should be false',
|
||
|
diag: {
|
||
|
at: at,
|
||
|
stack: stack,
|
||
|
operator: 'equal',
|
||
|
expected: false,
|
||
|
actual: true
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
stream.pipe(concat(function (body) {
|
||
|
var body = body.toString('utf8');
|
||
|
body = stripAt(body);
|
||
|
tt.equal(
|
||
|
body,
|
||
|
'TAP version 13\n'
|
||
|
+ '# t.equal stack trace\n'
|
||
|
+ 'not ok 1 true should be false\n'
|
||
|
+ ' ---\n'
|
||
|
+ ' operator: equal\n'
|
||
|
+ ' expected: false\n'
|
||
|
+ ' actual: true\n'
|
||
|
+ ' stack: |-\n'
|
||
|
+ ' '
|
||
|
+ stack.replace(/\n/g, '\n ') + '\n'
|
||
|
+ ' ...\n'
|
||
|
+ '\n'
|
||
|
+ '1..1\n'
|
||
|
+ '# tests 1\n'
|
||
|
+ '# pass 0\n'
|
||
|
+ '# fail 1\n'
|
||
|
);
|
||
|
|
||
|
tt.deepEqual(getDiag(body), {
|
||
|
stack: stack,
|
||
|
operator: 'equal',
|
||
|
expected: false,
|
||
|
actual: true
|
||
|
});
|
||
|
}));
|
||
|
|
||
|
test('t.equal stack trace', function (t) {
|
||
|
t.plan(1);
|
||
|
t.equal(true, false, 'true should be false');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
tap.test('preserves stack trace for failed assertions where actual===falsy', function (tt) {
|
||
|
tt.plan(6);
|
||
|
|
||
|
var test = tape.createHarness();
|
||
|
var stream = test.createStream();
|
||
|
var parser = stream.pipe(tapParser());
|
||
|
|
||
|
var stack = '';
|
||
|
parser.once('assert', function (data) {
|
||
|
tt.equal(typeof data.diag.at, 'string');
|
||
|
tt.equal(typeof data.diag.stack, 'string');
|
||
|
at = data.diag.at || '';
|
||
|
stack = data.diag.stack || '';
|
||
|
tt.ok(/^Error: false should be true(\n at .+)+/.exec(stack), 'stack should be a stack');
|
||
|
tt.deepEqual(data, {
|
||
|
ok: false,
|
||
|
id: 1,
|
||
|
name: 'false should be true',
|
||
|
diag: {
|
||
|
at: at,
|
||
|
stack: stack,
|
||
|
operator: 'equal',
|
||
|
expected: true,
|
||
|
actual: false
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
stream.pipe(concat(function (body) {
|
||
|
var body = body.toString('utf8');
|
||
|
body = stripAt(body);
|
||
|
tt.equal(
|
||
|
body,
|
||
|
'TAP version 13\n'
|
||
|
+ '# t.equal stack trace\n'
|
||
|
+ 'not ok 1 false should be true\n'
|
||
|
+ ' ---\n'
|
||
|
+ ' operator: equal\n'
|
||
|
+ ' expected: true\n'
|
||
|
+ ' actual: false\n'
|
||
|
+ ' stack: |-\n'
|
||
|
+ ' '
|
||
|
+ stack.replace(/\n/g, '\n ') + '\n'
|
||
|
+ ' ...\n'
|
||
|
+ '\n'
|
||
|
+ '1..1\n'
|
||
|
+ '# tests 1\n'
|
||
|
+ '# pass 0\n'
|
||
|
+ '# fail 1\n'
|
||
|
);
|
||
|
|
||
|
tt.deepEqual(getDiag(body), {
|
||
|
stack: stack,
|
||
|
operator: 'equal',
|
||
|
expected: true,
|
||
|
actual: false
|
||
|
});
|
||
|
}));
|
||
|
|
||
|
test('t.equal stack trace', function (t) {
|
||
|
t.plan(1);
|
||
|
t.equal(false, true, 'false should be true');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function getDiag(body) {
|
||
|
var yamlStart = body.indexOf(' ---');
|
||
|
var yamlEnd = body.indexOf(' ...\n');
|
||
|
var diag = body.slice(yamlStart, yamlEnd).split('\n').map(function (line) {
|
||
|
return line.slice(2);
|
||
|
}).join('\n');
|
||
|
|
||
|
// Get rid of 'at' variable (which has a line number / path of its own that's
|
||
|
// difficult to check).
|
||
|
var withStack = yaml.safeLoad(diag);
|
||
|
delete withStack.at;
|
||
|
return withStack;
|
||
|
}
|
||
|
|
||
|
function stripAt(body) {
|
||
|
return body.replace(/^\s*at:\s+Test.*$\n/m, '');
|
||
|
}
|