Skip to content

Commit 736a044

Browse files
author
vdemedes
committed
add TAP support
1 parent b02e5ec commit 736a044

3 files changed

Lines changed: 99 additions & 9 deletions

File tree

cli.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var updateNotifier = require('update-notifier');
2323
var chalk = require('chalk');
2424
var Promise = require('bluebird');
2525
var log = require('./lib/logger');
26+
var tap = require('./lib/tap');
2627
var Api = require('./api');
2728

2829
// Bluebird specific
@@ -36,7 +37,8 @@ var cli = meow([
3637
' --init Add AVA to your project',
3738
' --fail-fast Stop after first test failure',
3839
' --serial Run tests serially',
39-
' --require Module to preload (Can be repeated)',
40+
' --require Module to preload (Can be repeated)',,
41+
' --tap Generate TAP output',
4042
'',
4143
'Examples',
4244
' ava',
@@ -54,7 +56,8 @@ var cli = meow([
5456
],
5557
boolean: [
5658
'fail-fast',
57-
'serial'
59+
'serial',
60+
'tap'
5861
]
5962
});
6063

@@ -65,7 +68,11 @@ if (cli.flags.init) {
6568
return;
6669
}
6770

68-
log.write();
71+
if (cli.flags.tap) {
72+
tap.start();
73+
} else {
74+
log.write();
75+
}
6976

7077
var api = new Api(cli.input, {
7178
failFast: cli.flags.failFast,
@@ -74,6 +81,11 @@ var api = new Api(cli.input, {
7481
});
7582

7683
api.on('test', function (test) {
84+
if (cli.flags.tap) {
85+
tap.test(test);
86+
return;
87+
}
88+
7789
if (test.error) {
7890
log.error(test.title, chalk.red(test.error.message));
7991
} else {
@@ -87,17 +99,26 @@ api.on('test', function (test) {
8799
});
88100

89101
api.on('error', function (data) {
102+
if (cli.flags.tap) {
103+
tap.unhandledError(data);
104+
return;
105+
}
106+
90107
log.unhandledError(data.type, data.file, data);
91108
});
92109

93110
api.run()
94111
.then(function () {
95-
log.write();
96-
log.report(api.passCount, api.failCount, api.rejectionCount, api.exceptionCount);
97-
log.write();
98-
99-
if (api.failCount > 0) {
100-
log.errors(api.errors);
112+
if (cli.flags.tap) {
113+
tap.finish(api.passCount, api.failCount, api.rejectionCount, api.exceptionCount);
114+
} else {
115+
log.write();
116+
log.report(api.passCount, api.failCount, api.rejectionCount, api.exceptionCount);
117+
log.write();
118+
119+
if (api.failCount > 0) {
120+
log.errors(api.errors);
121+
}
101122
}
102123

103124
process.stdout.write('');

lib/tap.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict';
2+
var format = require('util').format;
3+
4+
// Parses stack trace and extracts original function name, file name and line.
5+
function getSourceFromStack(stack, index) {
6+
return stack
7+
.split('\n')
8+
.slice(index, index + 1)
9+
.join('')
10+
.replace(/^\s+at /, '');
11+
}
12+
13+
exports.start = function () {
14+
console.log('TAP version 13');
15+
};
16+
17+
var i = 0;
18+
19+
exports.test = function (test) {
20+
var output = [];
21+
22+
output.push('# ' + test.title);
23+
24+
if (test.error) {
25+
output.push(format('not ok %d - %s', ++i, test.error.message));
26+
output.push(' ---');
27+
output.push(' operator: ' + test.error.operator);
28+
output.push(' expected: ' + test.error.expected);
29+
output.push(' actual: ' + test.error.actual);
30+
output.push(' at: ' + getSourceFromStack(test.error.stack, 3));
31+
output.push(' ...');
32+
} else {
33+
output.push(format('ok %d - %s', ++i, test.title));
34+
}
35+
36+
console.log(output.join('\n'));
37+
};
38+
39+
exports.unhandledError = function (err) {
40+
var output = [];
41+
42+
output.push('# ' + err.message);
43+
output.push(format('not ok %d - %s', ++i, err.message));
44+
output.push(' ---');
45+
output.push(' name: ' + err.name);
46+
output.push(' at: ' + getSourceFromStack(err.stack, 1));
47+
output.push(' ...');
48+
49+
console.log(output.join('\n'));
50+
};
51+
52+
exports.finish = function (passCount, failCount, rejectionCount, exceptionCount) {
53+
console.log();
54+
console.log('1..' + (passCount + failCount));
55+
console.log('# tests ' + (passCount + failCount));
56+
console.log('# pass ' + passCount);
57+
console.log('# fail ' + (failCount + rejectionCount + exceptionCount));
58+
console.log();
59+
};

readme.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Even though JavaScript is single-threaded, IO in Node.js can happen in parallel
3333
- [Async function support](#async-function-support)
3434
- [Observable support](#observable-support)
3535
- [Enhanced asserts](#enhanced-asserts)
36+
- [Optional TAP output](#optional-tap-output)
3637

3738

3839
## Test syntax
@@ -105,6 +106,7 @@ $ ava --help
105106
--fail-fast Stop after first test failure
106107
--serial Run tests serially
107108
--require Module to preload (Can be repeated)
109+
--tap Generate TAP output
108110
109111
Examples
110112
ava
@@ -456,6 +458,14 @@ test.cb(t => {
456458
});
457459
```
458460

461+
### Optional TAP output
462+
463+
AVA can generate TAP output via `--tap` option for use with any 3rd-party reporters.
464+
465+
```bash
466+
$ ava --tap | tap-spec
467+
```
468+
459469

460470
## API
461471

0 commit comments

Comments
 (0)