blob: 5239cad4c2bb45e765d56860f23e51a99a183470 [file] [log] [blame]
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 15 plan != count",
" ---",
" operator: fail",
" expected: 4",
" actual: 3",
" ...",
"",
"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: 15,
ok: false,
raw: 'not ok 15 plan != count',
test: 1,
type: 'plan'
}
],
'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');
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();
});