From b73d2bfb69364f5332f5958bca2c69099aedc290 Mon Sep 17 00:00:00 2001 From: Michael Hayes Date: Wed, 12 Aug 2015 12:13:46 -0700 Subject: [PATCH] improve yaml formatting of diagnostic information --- lib/results.js | 19 ++++++---- package.json | 6 ++- test/circular-things.js | 59 +++++++++++++---------------- test/deep-equal-failure.js | 68 +++++++++++++++++++++++++++++++++ test/stackTrace.js | 77 ++++++++++++++++++++++++++++++++++++++ test/undef.js | 6 ++- 6 files changed, 191 insertions(+), 44 deletions(-) create mode 100644 test/deep-equal-failure.js create mode 100644 test/stackTrace.js diff --git a/lib/results.js b/lib/results.js index 18ac3ba8..b9f6ac4d 100644 --- a/lib/results.js +++ b/lib/results.js @@ -4,6 +4,8 @@ var through = require('through'); var resumer = require('resumer'); var inspect = require('object-inspect'); var hasOwn = Object.prototype.hasOwnProperty; +var regexpTest = RegExp.prototype.test; +var yamlIndicators = /\:|\-|\?/; var nextTick = typeof setImmediate !== 'undefined' ? setImmediate : process.nextTick @@ -146,9 +148,9 @@ function encodeResult (res, count) { var ex = inspect(res.expected); var ac = inspect(res.actual); - if (Math.max(ex.length, ac.length) > 65) { - output += inner + 'expected:\n' + inner + ' ' + ex + '\n'; - output += inner + 'actual:\n' + inner + ' ' + ac + '\n'; + if (Math.max(ex.length, ac.length) > 65 || invalidYaml(ex) || invalidYaml(ac)) { + output += inner + 'expected: |-\n' + inner + ' ' + ex + '\n'; + output += inner + 'actual: |-\n' + inner + ' ' + ac + '\n'; } else { output += inner + 'expected: ' + ex + '\n'; @@ -160,10 +162,9 @@ function encodeResult (res, count) { } 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 += inner + 'stack: |-\n'; + for (var i = 0; i < lines.length; i++) { + output += inner + ' ' + lines[i] + '\n'; } } @@ -188,3 +189,7 @@ function getNextTest (results) { function has (obj, prop) { return hasOwn.call(obj, prop); } + +function invalidYaml (str) { + return regexpTest.call(yamlIndicators, str); +} diff --git a/package.json b/package.json index d999085a..80e10d36 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "through": "~2.3.4" }, "devDependencies": { - "tap": "~0.7.1", + "concat-stream": "~1.4.1", "falafel": "~1.0.1", - "concat-stream": "~1.4.1" + "js-yaml": "^3.3.1", + "tap": "~0.7.1", + "tap-parser": "^1.1.6" }, "scripts": { "test": "tap test/*.js" diff --git a/test/circular-things.js b/test/circular-things.js index 1a0368d6..590ae430 100644 --- a/test/circular-things.js +++ b/test/circular-things.js @@ -1,43 +1,36 @@ var tape = require('../'); var tap = require('tap'); +var concat = require('concat-stream'); tap.test('circular test', function (assert) { var test = tape.createHarness({ exit : false }); - var tc = tap.createConsumer(); + assert.plan(1); - var rows = []; - tc.on('data', function (r) { rows.push(r) }); - tc.on('end', function () { - // console.log("rs", rows) - - // console.log("deepEqual?") - - assert.same(rows, [ - "TAP version 13" - , "circular" - , { id: 1 - , ok: false - , name: " should be equal" - , operator: "equal" - , expected: "{}" - , actual: '{ circular: [Circular] }' - } - , "tests 1" - , "pass 0" - , "fail 1" - ]) - assert.end() - }) - - // tt.equal(10, 10) - // tt.end() - - test.createStream().pipe(tc); + test.createStream().pipe(concat(function (body) { + assert.equal( + body.toString('utf8'), + 'TAP version 13\n' + + '# circular\n' + + 'not ok 1 should be equal\n' + + ' ---\n' + + ' operator: equal\n' + + ' expected: |-\n' + + ' {}\n' + + ' actual: |-\n' + + ' { circular: [Circular] }\n' + + ' ...\n' + + '\n' + + '1..1\n' + + '# tests 1\n' + + '# pass 0\n' + + '# fail 1\n' + ); + })); test("circular", function (t) { - t.plan(1) - var circular = {} - circular.circular = circular - t.equal(circular, {}) + t.plan(1); + var circular = {}; + circular.circular = circular; + t.equal(circular, {}); }) }) diff --git a/test/deep-equal-failure.js b/test/deep-equal-failure.js new file mode 100644 index 00000000..2467f763 --- /dev/null +++ b/test/deep-equal-failure.js @@ -0,0 +1,68 @@ +var tape = require('../'); +var tap = require('tap'); +var concat = require('concat-stream'); +var tapParser = require('tap-parser'); +var yaml = require('js-yaml'); + +tap.test('deep equal failure', function (assert) { + var test = tape.createHarness({ exit : false }); + var stream = test.createStream(); + var parser = tapParser(); + assert.plan(3); + + stream.pipe(parser); + stream.pipe(concat(function (body) { + assert.equal( + body.toString('utf8'), + 'TAP version 13\n' + + '# deep equal\n' + + 'not ok 1 should be equal\n' + + ' ---\n' + + ' operator: equal\n' + + ' expected: |-\n' + + ' { b: 2 }\n' + + ' actual: |-\n' + + ' { a: 1 }\n' + + ' ...\n' + + '\n' + + '1..1\n' + + '# tests 1\n' + + '# pass 0\n' + + '# fail 1\n' + ); + + assert.deepEqual(getDiag(body), { + operator: 'equal', + expected: '{ b: 2 }', + actual: '{ a: 1 }' + }); + })); + + parser.once('assert', function (data) { + assert.deepEqual(data, { + ok: false, + id: 1, + name: 'should be equal', + diag: { + operator: 'equal', + expected: '{ b: 2 }', + actual: '{ a: 1 }' + } + }); + }); + + test("deep equal", function (t) { + t.plan(1); + t.equal({a: 1}, {b: 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/stackTrace.js b/test/stackTrace.js new file mode 100644 index 00000000..bde1bc50 --- /dev/null +++ b/test/stackTrace.js @@ -0,0 +1,77 @@ +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) { + 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') + 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); + }); +}); + +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/undef.js b/test/undef.js index e856a54b..d3ae8d40 100644 --- a/test/undef.js +++ b/test/undef.js @@ -14,8 +14,10 @@ tap.test('array test', function (tt) { + 'not ok 1 should be equivalent\n' + ' ---\n' + ' operator: deepEqual\n' - + ' expected: { beep: undefined }\n' - + ' actual: {}\n' + + ' expected: |-\n' + + ' { beep: undefined }\n' + + ' actual: |-\n' + + ' {}\n' + ' ...\n' + '\n' + '1..1\n'