From 93026823b0606021adac0042ef2da6865607ee90 Mon Sep 17 00:00:00 2001 From: Tristan Davies Date: Tue, 17 May 2016 11:14:26 -0300 Subject: [PATCH] [New] show full error stack on failure --- lib/results.js | 9 ++++-- test/circular-things.js | 9 +++++- test/common.js | 56 ++++++++++++++++++++++++++++++++++ test/deep-equal-failure.js | 39 +++++++++++++++--------- test/double_end.js | 31 ++++++++++++++++++- test/double_end/double.js | 8 +++-- test/exit.js | 22 ++++++++++++-- test/fail.js | 12 +++++++- test/stackTrace.js | 61 ++++++++++++++++++++++++++++++++++++++ test/throws.js | 49 +++++++++++++++++++++++++++++- test/timeoutAfter.js | 7 ++++- test/too_many.js | 12 +++++++- test/undef.js | 9 +++++- 13 files changed, 295 insertions(+), 29 deletions(-) create mode 100644 test/common.js diff --git a/lib/results.js b/lib/results.js index efc60ce3..35bf09f3 100644 --- a/lib/results.js +++ b/lib/results.js @@ -1,3 +1,4 @@ +var defined = require('defined'); var EventEmitter = require('events').EventEmitter; var inherits = require('inherits'); var through = require('through'); @@ -157,8 +158,12 @@ function encodeResult (res, count) { 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'); + + var actualStack = res.actual && res.actual.stack; + var errorStack = res.error && res.error.stack; + var stack = defined(actualStack, errorStack); + if (stack) { + var lines = String(stack).split('\n'); output += inner + 'stack: |-\n'; for (var i = 0; i < lines.length; i++) { output += inner + ' ' + lines[i] + '\n'; diff --git a/test/circular-things.js b/test/circular-things.js index 590ae430..bbabc919 100644 --- a/test/circular-things.js +++ b/test/circular-things.js @@ -2,13 +2,15 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('circular test', function (assert) { var test = tape.createHarness({ exit : false }); assert.plan(1); test.createStream().pipe(concat(function (body) { assert.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# circular\n' + 'not ok 1 should be equal\n' @@ -18,6 +20,11 @@ tap.test('circular test', function (assert) { + ' {}\n' + ' actual: |-\n' + ' { circular: [Circular] }\n' + + ' stack: |-\n' + + ' Error: should be equal\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/circular-things.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '\n' + '1..1\n' diff --git a/test/common.js b/test/common.js new file mode 100644 index 00000000..22d7854c --- /dev/null +++ b/test/common.js @@ -0,0 +1,56 @@ +var yaml = require('js-yaml'); + +module.exports.getDiag = function (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'); + + // The stack trace will vary depending on where the code is run, so just + // strip it out. + var withStack = yaml.safeLoad(diag); + delete withStack.stack; + return withStack; +} + +// There are three challenges associated with checking the stack traces included +// in errors: +// 1) The base checkout directory of tape might change. Because stack traces +// include absolute paths, the stack traces will change depending on the +// checkout path. We handle this by replacing the base test directory with a +// placeholder $TEST variable. +// 2) Line positions within the file might change. We handle this by replacing +// line and column markers with placeholder $LINE and $COL "variables" +// 3) Stacks themselves change frequently with refactoring. We've even run into +// issues with node library refactorings "breaking" stack traces. Most of +// these changes are irrelevant to the tests themselves. To counter this, we +// strip out all stack frames that aren't directly under our test directory, +// and replace them with placeholders. +module.exports.stripFullStack = function (output) { + var stripped = ' [... stack stripped ...]'; + var withDuplicates = output.split('\n').map(function (line) { + var m = line.match(/[ ]{8}at .*\((.*)\)/); + + var stripChangingData = function (line) { + var withoutDirectory = line.replace(__dirname, '$TEST'); + var withoutLineNumbers = withoutDirectory.replace(/:\d+:\d+/g, ':$LINE:$COL'); + return withoutLineNumbers; + } + + if (m) { + if (m[1].slice(0, __dirname.length) === __dirname) { + return stripChangingData(line); + } + return stripped; + } + return stripChangingData(line); + }) + + var deduped = withDuplicates.filter(function (line, ix) { + var hasPrior = line === stripped && withDuplicates[ix - 1] === stripped; + return !hasPrior; + }); + + return deduped.join('\n'); +} diff --git a/test/deep-equal-failure.js b/test/deep-equal-failure.js index 3f12b30e..4836037b 100644 --- a/test/deep-equal-failure.js +++ b/test/deep-equal-failure.js @@ -2,7 +2,10 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); var tapParser = require('tap-parser'); -var yaml = require('js-yaml'); +var common = require('./common'); + +var getDiag = common.getDiag; +var stripFullStack = common.stripFullStack; tap.test('deep equal failure', function (assert) { var test = tape.createHarness({ exit : false }); @@ -13,7 +16,7 @@ tap.test('deep equal failure', function (assert) { stream.pipe(parser); stream.pipe(concat(function (body) { assert.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# deep equal\n' + 'not ok 1 should be equal\n' @@ -23,6 +26,11 @@ tap.test('deep equal failure', function (assert) { + ' { b: 2 }\n' + ' actual: |-\n' + ' { a: 1 }\n' + + ' stack: |-\n' + + ' Error: should be equal\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/deep-equal-failure.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '\n' + '1..1\n' @@ -39,6 +47,7 @@ tap.test('deep equal failure', function (assert) { })); parser.once('assert', function (data) { + delete data.diag.stack; assert.deepEqual(data, { ok: false, id: 1, @@ -66,7 +75,7 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { stream.pipe(parser); stream.pipe(concat(function (body) { assert.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# deep equal\n' + 'not ok 1 should be equal\n' @@ -76,6 +85,11 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { + ' { a: { a1: { a2: { a3: { a4: { a5: 2 } } } } } }\n' + ' actual: |-\n' + ' { a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }\n' + + ' stack: |-\n' + + ' Error: should be equal\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/deep-equal-failure.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '\n' + '1..1\n' @@ -92,6 +106,7 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { })); parser.once('assert', function (data) { + delete data.diag.stack; assert.deepEqual(data, { ok: false, id: 1, @@ -119,7 +134,7 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { stream.pipe(parser); stream.pipe(concat(function (body) { assert.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# deep equal\n' + 'not ok 1 should be equal\n' @@ -129,6 +144,11 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { + ' { a: { a1: { a2: { a3: { a4: [Object] } } } } }\n' + ' actual: |-\n' + ' { a: { a1: { a2: { a3: { a4: [Object] } } } } }\n' + + ' stack: |-\n' + + ' Error: should be equal\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/deep-equal-failure.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '\n' + '1..1\n' @@ -145,6 +165,7 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { })); parser.once('assert', function (data) { + delete data.diag.stack; assert.deepEqual(data, { ok: false, id: 1, @@ -162,13 +183,3 @@ tap.test('deep equal failure, depth 6, without option', function (assert) { t.equal({ a: { a1: { a2: { a3: { a4: { a5: 1 } } } } } }, { a: { a1: { a2: { a3: { a4: { a5: 2 } } } } } }); }); }) - -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'); - - return yaml.safeLoad(diag); -} diff --git a/test/double_end.js b/test/double_end.js index 624ce3ac..212606e9 100644 --- a/test/double_end.js +++ b/test/double_end.js @@ -3,6 +3,8 @@ var path = require('path'); var concat = require('concat-stream'); var spawn = require('child_process').spawn; +var stripFullStack = require('./common').stripFullStack; + test(function (t) { t.plan(2); var ps = spawn(process.execPath, [path.join(__dirname, 'double_end', 'double.js')]); @@ -10,13 +12,40 @@ test(function (t) { t.equal(code, 1); }); ps.stdout.pipe(concat(function (body) { - t.equal(body.toString('utf8'), [ + // The implementation of node's timer library has changed over time. We + // need to reverse engineer the error we expect to see. + + // This code is unfortunately by necessity highly coupled to node + // versions, and may require tweaking with future versions of the timers + // library. + function doEnd() { throw new Error() }; + var to = setTimeout(doEnd, 5000); + clearTimeout(to); + to._onTimeout = doEnd; + + var stackExpected; + try { + to._onTimeout(); + } + catch (e) { + stackExpected = stripFullStack(e.stack).split('\n')[1]; + stackExpected = stackExpected.replace('double_end.js', 'double_end/double.js'); + stackExpected = stackExpected.trim(); + } + + var stripped = stripFullStack(body.toString('utf8')); + t.equal(stripped, [ 'TAP version 13', '# double end', 'ok 1 should be equal', 'not ok 2 .end() called twice', ' ---', ' operator: fail', + ' stack: |-', + ' Error: .end() called twice', + ' [... stack stripped ...]', + ' ' + stackExpected, + ' [... stack stripped ...]', ' ...', '', '1..2', diff --git a/test/double_end/double.js b/test/double_end/double.js index 44734824..43929e51 100644 --- a/test/double_end/double.js +++ b/test/double_end/double.js @@ -1,9 +1,11 @@ var test = require('../../'); test('double end', function (t) { + function doEnd() { + t.end(); + } + t.equal(1 + 1, 2); t.end(); - setTimeout(function () { - t.end(); - }, 5); + setTimeout(doEnd, 5); }); diff --git a/test/exit.js b/test/exit.js index 963e6b08..5736895d 100644 --- a/test/exit.js +++ b/test/exit.js @@ -3,6 +3,8 @@ var path = require('path'); var spawn = require('child_process').spawn; var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('exit ok', function (t) { t.plan(2); @@ -38,7 +40,7 @@ tap.test('exit fail', function (t) { t.plan(2); var tc = function (rows) { - t.same(rows.toString('utf8'), [ + t.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# array', 'ok 1 should be equivalent', @@ -50,6 +52,14 @@ tap.test('exit fail', function (t) { ' operator: deepEqual', ' expected: [ [ 1, 2, [ 3, 4444 ] ], [ 5, 6 ] ]', ' actual: [ [ 1, 2, [ 3, 4 ] ], [ 5, 6 ] ]', + ' stack: |-', + ' Error: should be equivalent', + ' [... stack stripped ...]', + ' at $TEST/exit/fail.js:$LINE:$COL', + ' at eval (eval at ($TEST/exit/fail.js:$LINE:$COL), :$LINE:$COL)', + ' at eval (eval at ($TEST/exit/fail.js:$LINE:$COL), :$LINE:$COL)', + ' at Test. ($TEST/exit/fail.js:$LINE:$COL)', + ' [... stack stripped ...]', ' ...', '', '1..5', @@ -70,7 +80,7 @@ tap.test('too few exit', function (t) { t.plan(2); var tc = function (rows) { - t.same(rows.toString('utf8'), [ + t.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# array', 'ok 1 should be equivalent', @@ -83,6 +93,9 @@ tap.test('too few exit', function (t) { ' operator: fail', ' expected: 6', ' actual: 5', + ' stack: |-', + ' Error: plan != count', + ' [... stack stripped ...]', ' ...', '', '1..6', @@ -103,7 +116,7 @@ tap.test('more planned in a second test', function (t) { t.plan(2); var tc = function (rows) { - t.same(rows.toString('utf8'), [ + t.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# first', 'ok 1 should be truthy', @@ -114,6 +127,9 @@ tap.test('more planned in a second test', function (t) { ' operator: fail', ' expected: 2', ' actual: 1', + ' stack: |-', + ' Error: plan != count', + ' [... stack stripped ...]', ' ...', '', '1..3', diff --git a/test/fail.js b/test/fail.js index 54c544cc..820cf27e 100644 --- a/test/fail.js +++ b/test/fail.js @@ -3,12 +3,14 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('array test', function (tt) { tt.plan(1); var test = tape.createHarness({ exit : false }); var tc = function (rows) { - tt.same(rows.toString('utf8'), [ + tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# array', 'ok 1 should be equivalent', @@ -20,6 +22,14 @@ tap.test('array test', function (tt) { ' operator: deepEqual', ' expected: [ [ 1, 2, [ 3, 4444 ] ], [ 5, 6 ] ]', ' actual: [ [ 1, 2, [ 3, 4 ] ], [ 5, 6 ] ]', + ' stack: |-', + ' Error: should be equivalent', + ' [... stack stripped ...]', + ' at $TEST/fail.js:$LINE:$COL', + ' at eval (eval at ($TEST/fail.js:$LINE:$COL), :$LINE:$COL)', + ' at eval (eval at ($TEST/fail.js:$LINE:$COL), :$LINE:$COL)', + ' at Test. ($TEST/fail.js:$LINE:$COL)', + ' [... stack stripped ...]', ' ...', '', '1..5', diff --git a/test/stackTrace.js b/test/stackTrace.js index bde1bc50..110da365 100644 --- a/test/stackTrace.js +++ b/test/stackTrace.js @@ -66,6 +66,67 @@ tap.test('preserves stack trace with newlines', function (tt) { }); }); +tap.test('preserves stack trace for failed assertions', function (tt) { + tt.plan(5); + + 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.stack, 'string') + 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: { + stack: stack, + operator: 'equal', + expected: false, + actual: true + } + }); + }); + + stream.pipe(concat(function (body) { + var body = body.toString('utf8') + 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: 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, 'false should be true'); + }); +}); + function getDiag (body) { var yamlStart = body.indexOf(' ---'); var yamlEnd = body.indexOf(' ...\n'); diff --git a/test/throws.js b/test/throws.js index 31ab9a45..bc602f0e 100644 --- a/test/throws.js +++ b/test/throws.js @@ -2,6 +2,8 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + function fn() { throw new TypeError('RegExp'); } @@ -20,7 +22,7 @@ tap.test('failures', function (tt) { var test = tape.createHarness(); test.createStream().pipe(concat(function (body) { tt.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# non functions\n' + 'not ok 1 should throw\n' @@ -30,6 +32,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage() + "] message: '" + getNonFunctionMessage() + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage(undefined) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 2 should throw\n' + ' ---\n' @@ -38,6 +45,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(null) + "] message: '" + getNonFunctionMessage(null) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage(null) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 3 should throw\n' + ' ---\n' @@ -46,6 +58,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(true) + "] message: '" + getNonFunctionMessage(true) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage(true) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 4 should throw\n' + ' ---\n' @@ -54,6 +71,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(false) + "] message: '" + getNonFunctionMessage(false) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage(false) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 5 should throw\n' + ' ---\n' @@ -62,6 +84,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage('abc') + "] message: '" + getNonFunctionMessage('abc') + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage('abc') + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 6 should throw\n' + ' ---\n' @@ -70,6 +97,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage(/a/g) + "] message: '" + getNonFunctionMessage(/a/g) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage(/a/g) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 7 should throw\n' + ' ---\n' @@ -78,6 +110,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage([]) + "] message: '" + getNonFunctionMessage([]) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage([]) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + 'not ok 8 should throw\n' + ' ---\n' @@ -86,6 +123,11 @@ tap.test('failures', function (tt) { + ' undefined\n' + ' actual: |-\n' + " { [TypeError: " + getNonFunctionMessage({}) + "] message: '" + getNonFunctionMessage({}) + "' }\n" + + ' stack: |-\n' + + ' TypeError: ' + getNonFunctionMessage({}) + '\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '# function\n' + 'not ok 9 should throw\n' @@ -93,6 +135,11 @@ tap.test('failures', function (tt) { + ' operator: throws\n' + ' expected: undefined\n' + ' actual: undefined\n' + + ' stack: |-\n' + + ' Error: should throw\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/throws.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '# custom error messages\n' + 'ok 10 "message" is enumerable\n' diff --git a/test/timeoutAfter.js b/test/timeoutAfter.js index e44e3c78..7b8bf647 100644 --- a/test/timeoutAfter.js +++ b/test/timeoutAfter.js @@ -2,17 +2,22 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('timeoutAfter test', function (tt) { tt.plan(1); var test = tape.createHarness(); var tc = function (rows) { - tt.same(rows.toString('utf8'), [ + tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# timeoutAfter', 'not ok 1 test timed out after 1ms', ' ---', ' operator: fail', + ' stack: |-', + ' Error: test timed out after 1ms', + ' [... stack stripped ...]', ' ...', '', '1..1', diff --git a/test/too_many.js b/test/too_many.js index 233a7abc..e06cb639 100644 --- a/test/too_many.js +++ b/test/too_many.js @@ -3,12 +3,14 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('array test', function (tt) { tt.plan(1); var test = tape.createHarness({ exit : false }); var tc = function (rows) { - tt.same(rows.toString('utf8'), [ + tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', '# array', 'ok 1 should be equivalent', @@ -20,6 +22,14 @@ tap.test('array test', function (tt) { ' operator: fail', ' expected: 3', ' actual: 4', + ' stack: |-', + ' Error: plan != count', + ' [... stack stripped ...]', + ' at $TEST/too_many.js:$LINE:$COL', + ' at eval (eval at ($TEST/too_many.js:$LINE:$COL), :$LINE:$COL)', + ' at eval (eval at ($TEST/too_many.js:$LINE:$COL), :$LINE:$COL)', + ' at Test. ($TEST/too_many.js:$LINE:$COL)', + ' [... stack stripped ...]', ' ...', 'ok 6 should be equivalent', '', diff --git a/test/undef.js b/test/undef.js index d3ae8d40..a3101a26 100644 --- a/test/undef.js +++ b/test/undef.js @@ -2,13 +2,15 @@ var tape = require('../'); var tap = require('tap'); var concat = require('concat-stream'); +var stripFullStack = require('./common').stripFullStack; + tap.test('array test', function (tt) { tt.plan(1); var test = tape.createHarness(); test.createStream().pipe(concat(function (body) { tt.equal( - body.toString('utf8'), + stripFullStack(body.toString('utf8')), 'TAP version 13\n' + '# undef\n' + 'not ok 1 should be equivalent\n' @@ -18,6 +20,11 @@ tap.test('array test', function (tt) { + ' { beep: undefined }\n' + ' actual: |-\n' + ' {}\n' + + ' stack: |-\n' + + ' Error: should be equivalent\n' + + ' [... stack stripped ...]\n' + + ' at Test. ($TEST/undef.js:$LINE:$COL)\n' + + ' [... stack stripped ...]\n' + ' ...\n' + '\n' + '1..1\n'