UNPKG

@randomgoods/tap-out

Version:
788 lines (646 loc) 16.7 kB
var parser = require('../'); var test = require('tape'); test('output event', function (t) { t.plan(1); var mockTap = [ '# is true', 'ok 1 true value', 'ok 2 true value', '1..2' ]; var p = parser(); p.on('output', function (output) { t.deepEqual(output, { asserts: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' } ], fail: [], pass: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' } ], results: [], tests: [ { name: 'is true', number: 1, raw: '# is true', type: 'test' } ], versions: [], comments: [], plans: [{ from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }], errors: [] }, 'output data'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('output callback', function (t) { t.plan(1); var mockTap = [ '# is true', 'ok 1 true value', 'ok 2 true value', '1..2' ]; var p = parser(function (err, output) { t.deepEqual(output, { asserts: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' } ], fail: [], pass: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' } ], results: [], tests: [ { name: 'is true', number: 1, raw: '# is true', type: 'test' } ], versions: [], comments: [], plans: [{ from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' }], errors: [] }, 'output data'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('tests', function (t) { t.plan(1); var mockTap = [ '# is true', 'ok 1 true value', 'ok 2 true value' ]; var p = parser(); p.on('test', function (test) { t.deepEqual(test, { type: 'test', name: 'is true', raw: '# is true', number: 1 }, 'test is parsed'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('asserts', function (t) { t.plan(2); var mockTap = [ '# is true', 'ok 1 true value', 'ok 2 true value' ]; var p = parser(); var asserts = []; p.on('assert', function (assert) { asserts.push(assert); }); p.on('output', function () { t.deepEqual(asserts[0], { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, 'assert 1') t.deepEqual(asserts[1], { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }, 'assert 2') }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('results', function (t) { t.plan(3); var mockTap = [ '# tests 15', '# pass 13', '# fail 2' ]; var p = parser(); var results = []; p.on('result', function (result) { results.push(result); }); p.on('output', function () { t.deepEqual(results[0], { count: '15', name: 'tests', raw: '# tests 15', type: 'result' }, 'tests'); t.deepEqual(results[1], { count: '13', name: 'pass', raw: '# pass 13', type: 'result' }, 'pass'); t.deepEqual(results[2], { count: '2', name: 'fail', raw: '# fail 2', type: 'result' }, 'fail'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('version', function (t) { t.plan(1); var mockTap = [ 'TAP version 13' ]; var p = parser(); var results = []; p.on('version', function (version) { t.deepEqual(version, { raw: 'TAP version 13', type: 'version' }, 'version data'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('pass', function (t) { t.plan(2); var mockTap = [ '# is true', 'ok 1 true value', 'ok 2 true value' ]; var p = parser(); var passes = []; p.on('pass', function (pass) { passes.push(pass); }); p.on('output', function () { t.deepEqual(passes[0], { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, 'pass 1'); t.deepEqual(passes[1], { name: 'true value', number: 2, ok: true, raw: 'ok 2 true value', test: 1, type: 'assert' }, 'pass 2'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('failed assertion', function (t) { t.plan(1); var mockTap = [ "TAP version 13", "# is true", "ok 1 true value", "ok 2 true value", "not ok 3 strings match", " ---", " operator: equal", " expected: 'you'", " actual: 'me'", " at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)", " ...", "not ok 4 plan != count", " ---", " operator: fail", " expected: 4", " actual: 3", " ...", "ok 5 true value", "not ok 6 - failure", "not ok 15 - item not found", "", "1..15", ]; var fails = []; var p = parser(function () { t.deepEqual( fails, [ { error: { actual: 'me', at: { character: '5', file: '/Users/scott/www/divshot/divshot-cli/test/index.js', line: '8' }, expected: 'you', operator: 'equal', raw: [ " operator: equal", " expected: 'you'", " actual: 'me'", " at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)" ].join('\n') }, name: 'strings match', number: 3, ok: false, raw: 'not ok 3 strings match', test: 1, type: 'assert' }, { error: { actual: '3', expected: '4', operator: 'count', raw: [ " operator: fail", " expected: 4", " actual: 3" ].join('\n') }, name: 'plan != count', number: 4, ok: false, raw: 'not ok 4 plan != count', test: 1, type: 'plan' }, { error: { actual: undefined, expected: undefined, operator: undefined, at: undefined }, name: 'failure', number: 6, ok: false, raw: 'not ok 6 - failure', test: 1, type: 'assert' }, { error: { actual: undefined, expected: undefined, operator: undefined, at: undefined }, name: 'item not found', number: 15, ok: false, raw: 'not ok 15 - item not found', test: 1, type: 'assert' } ], 'fails' ); }); p.on('fail', function (fail) { fails.push(fail); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('plan', function (t) { var mockTap = [ '1..2', ]; var plans = []; var p = parser(function () { t.deepEqual(plans, [ { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' } ]); t.end(); }); p.on('plan', function (plan) { plans.push(plan); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); // NOTE: comments output the same as test names. // This makes it very difficult to parse them. // Ignoring them for now. Just don't use comments. test('comments', function (t) { t.ok(1) t.end() }); test('generic output', function (t) { var mockTap = [ "TAP version 13", "# is true", "ok 1 true value", "not ok 2 strings match", " ---", " operator: equal", " expected: 'you'", " actual: 'me'", " at: Test.<anonymous> (/Users/scott/www/divshot/divshot-cli/test/index.js:8:5)", " ...", "ok 3 true value", "this is a console log", "# false values", "ok 4 should be false", "ok 5 false value" ]; var comments = []; var p = parser(function (err, output) { t.deepEqual( comments, [ { type: 'comment', raw: 'this is a console log', test: 1 } ], 'one comment' ); t.end(); }); p.on('comment', function (comment) { comments.push(comment); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('handles HTTP error source', function (t) { t.plan(1); var mockTap = [ "TAP version 13", "# is true", "ok 1 true value", "ok 2 true value", "not ok 3 strings match", " ---", " operator: equal", " expected: 'you'", " actual: 'me'", " at: Test.<anonymous> (http://localhost:9966/index.js:8:5)", " ...", "not ok 15 plan != count", " ---", " operator: fail", " expected: 4", " actual: 3", " ...", "", "1..15", ]; var p = parser(); p.on('output', function (output) { var assert = output.fail[0]; t.deepEqual(assert.error.at, { character: '5', file: 'http://localhost:9966/index.js', line: '8' }); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('handles raw error string', function (t) { t.plan(1); var rawLines = [ " operator: deepEqual", " expected:", " { 0: 0, 1: 0, 10: 0, 11: 255, 12: 0, 13: 0, 14: 0, 15: 255, 2: 0, 3: 221, 4: 0, 5: 0, 6: 0, 7: 255, 8: 0, 9: 0 }", " actual:", " { 0: 0, 1: 0, 10: 0, 11: 255, 12: 0, 13: 0, 14: 0, 15: 255, 2: 0, 3: 255, 4: 0, 5: 0, 6: 0, 7: 255, 8: 0, 9: 0 }", " at: Test.<anonymous> (http://localhost:9966/index.js:8:5)" ]; var mockTap = [ "TAP version 13", "# is true", "ok 1 true value", "ok 2 true value", "not ok 3 arrays match", " ---" ].concat(rawLines).concat([ " ...", "not ok 15 plan != count", " ---", " operator: fail", " expected: 4", " actual: 3", " ...", "", "1..15", ]); var p = parser(); p.on('output', function (output) { var assert = output.fail[0]; t.deepEqual(assert.error.raw, rawLines.join('\n')); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('handles multiline error string with |-', function (t) { t.plan(2); var mockTap = [ "TAP version 13", "# is true", "ok 1 true value", "not ok 2 object deep equal with cross", " ---", " operator: deepEqual", " expected: |-", " { a: 1, b: 2 }", " actual: |-", " { a: 1, b: 3 }", " at: Test.<anonymous> (/Users/germ/Projects/a/b/test.js:7:5)", " ...", "", "1..2", ]; var p = parser(); p.on('output', function (output) { var assert = output.fail[0]; t.equal(assert.error.expected, '{ a: 1, b: 2 }'); t.equal(assert.error.actual, '{ a: 1, b: 3 }'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('handles multiline error stack with |-', function (t) { t.plan(2); var mockTap = [ "TAP version 13", "# promise error", "not ok 1 TypeError: foo", " ---", " operator: error", " expected: |-", " undefined", " actual: |-", " [TypeError: foo]", " at: process._tickCallback (internal/process/next_tick.js:103:7)", " stack: |-", " TypeError: foo", " at throwError (/Users/germ/Projects/a/b/test.js:17:9)", " at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)", " at process._tickCallback (internal/process/next_tick.js:103:7)", " ...", "", "1..1", "# tests 1", "# pass 0", "# fail 1" ]; var p = parser(); p.on('output', function (output) { var assert = output.fail[0]; t.equal(assert.error.stack, 'TypeError: foo\n' + 'at throwError (/Users/germ/Projects/a/b/test.js:17:9)\n' + 'at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)\n' + 'at process._tickCallback (internal/process/next_tick.js:103:7)\n' ); t.equal(assert.error.raw, ' operator: error\n' + ' expected: |-\n' + ' undefined\n' + ' actual: |-\n' + ' [TypeError: foo]\n' + ' at: process._tickCallback (internal/process/next_tick.js:103:7)\n' + ' stack: |-\n' + 'TypeError: foo\n' + 'at throwError (/Users/germ/Projects/a/b/test.js:17:9)\n' + 'at Promise.resolve.then (/Users/germ/Projects/a/b/test.js:24:5)\n' + 'at process._tickCallback (internal/process/next_tick.js:103:7)' ); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('output without plan', function (t) { t.plan(1); var mockTap = [ "# is true", "ok 1 true value", ]; var p = parser(); p.on('output', function (output) { t.deepEqual(output, { asserts: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' } ], fail: [], pass: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' } ], results: [], tests: [ { name: 'is true', number: 1, raw: '# is true', type: 'test' } ], versions: [], comments: [], plans: [], errors: [ { message: 'no plan provided', type: 'error' } ] }, 'output data with empty plans and no plan provided'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('output with assert count and plan mismatch', function (t) { t.plan(1); var mockTap = [ "# is true", "ok 1 true value", "1..2", ]; var p = parser(); p.on('output', function (output) { t.deepEqual(output, { asserts: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' } ], fail: [], pass: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' } ], results: [], tests: [ { name: 'is true', number: 1, raw: '# is true', type: 'test' } ], versions: [], comments: [], plans: [ { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' } ], errors: [ { message: 'incorrect number of assertions made', type: 'error' } ] }, 'output data with empty assert count and plan mismatch error'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); }); test('output with plan end and assertion number mismatch', function (t) { t.plan(1); var mockTap = [ "# is true", "ok 1 true value", 'ok 3 true value', "1..2", ]; var p = parser(); p.on('output', function (output) { t.deepEqual(output, { asserts: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 3, ok: true, raw: 'ok 3 true value', test: 1, type: 'assert' } ], fail: [], pass: [ { name: 'true value', number: 1, ok: true, raw: 'ok 1 true value', test: 1, type: 'assert' }, { name: 'true value', number: 3, ok: true, raw: 'ok 3 true value', test: 1, type: 'assert' } ], results: [], tests: [ { name: 'is true', number: 1, raw: '# is true', type: 'test' } ], versions: [], comments: [], plans: [ { from: 1, to: 2, raw: '1..2', skip: undefined, type: 'plan' } ], errors: [ { message: 'last assertion number does not equal the plan end', type: 'error' } ] }, 'output data with plan end error'); }); mockTap.forEach(function (line) { p.write(line + '\n'); }); p.end(); });