Skip to content

Commit 65a425f

Browse files
committed
Add -o --output-file option to store raw TAP
Fix #352 Needed to refactor the process hijacking stuff a little bit, otherwise the pipe to the output file would conflict with piping to the stdout reporter (or just stdout directly).
1 parent c9f4671 commit 65a425f

File tree

5 files changed

+73
-9
lines changed

5 files changed

+73
-9
lines changed

bin/run.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ function constructDefaultArgs () {
134134
functions: 0,
135135
lines: 0,
136136
statements: 0,
137-
jobs: 1
137+
jobs: 1,
138+
outputFile: null
138139
}
139140

140141
if (process.env.TAP_COLORS !== undefined)
@@ -162,7 +163,8 @@ function parseArgs (args, defaults) {
162163
j: 'jobs',
163164
R: 'reporter',
164165
t: 'timeout',
165-
s: 'save'
166+
s: 'save',
167+
o: 'output-file'
166168
}
167169

168170
// If we're running under Travis-CI with a Coveralls.io token,
@@ -350,6 +352,12 @@ function parseArgs (args, defaults) {
350352
options.color = false
351353
continue
352354

355+
case '--output-file':
356+
val = val || args[++i]
357+
if (val !== undefined)
358+
options.outputFile = val
359+
continue
360+
353361
case '--no-timeout':
354362
options.timeout = 0
355363
continue
@@ -727,12 +735,16 @@ function runTests (options) {
727735
var tap = require('../lib/tap.js')
728736

729737
tap.jobs = options.jobs
738+
tap.patchProcess()
730739

731740
// if not -Rtap, then output what the user wants.
732-
if (options.reporter !== 'tap') {
733-
tap.unpipe(process.stdout)
734-
tap.pipe(makeReporter(options))
735-
}
741+
// otherwise just dump to stdout
742+
tap.pipe(options.reporter === 'tap' ? process.stdout: makeReporter(options))
743+
744+
// need to replay the first version line, because the previous
745+
// line will have flushed it out to stdout or the reporter already.
746+
if (options.outputFile !== null)
747+
tap.pipe(fs.createWriteStream(options.outputFile)).write('TAP version 13\n')
736748

737749
saveFails(options, tap)
738750

bin/usage.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ Options:
4444
Available reporters:
4545
@@REPORTERS@@
4646

47+
-o<file> Send the raw TAP output to the specified
48+
--output-file=<file> file. Reporter output will still be
49+
printed to stdout, but the file will
50+
contain the raw TAP for later reply or
51+
analysis.
52+
4753
-s<file> --save=<file> If <file> exists, then it should be a line-
4854
delimited list of test files to run. If
4955
<file> is not present, then all command-line

lib/tap.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,17 @@ function onExitEvent (code) {
7474
TAP.prototype.push = function push () {
7575
// this resets push and pipe to standard values
7676
this.pipe(process.stdout)
77+
this.patchProcess()
78+
return this.push.apply(this, arguments)
79+
}
7780

81+
TAP.prototype.patchProcess = function () {
7882
monkeypatchEpipe()
7983
monkeypatchExit()
8084
process.on('uncaughtException', this.threw)
8185
process.on('unhandledRejection', function (er) {
8286
this.threw(er)
8387
}.bind(this))
84-
85-
return this.push.apply(this, arguments)
8688
}
8789

8890
TAP.prototype.onbail = function () {

test/rcfiles.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ var defaults = {
2929
jobs: 1,
3030
lines: 0,
3131
statements: 0,
32-
rcFile: osHomedir() + '/.taprc'
32+
rcFile: osHomedir() + '/.taprc',
33+
outputFile: null
3334
}
3435

3536
function runTest (rcFile, expect) { return function (t) {

test/runner-output-file.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
var t = require('../')
2+
var spawn = require('child_process').spawn
3+
var run = require.resolve('../bin/run.js')
4+
var fs = require('fs')
5+
var node = process.execPath
6+
var ok = require.resolve('./test/ok.js')
7+
8+
var args = [
9+
'-ofile.txt',
10+
'-Co file.txt',
11+
'-bCco=file.txt',
12+
'-o=file.txt',
13+
'--output-file=file.txt',
14+
'--output-file file.txt'
15+
]
16+
17+
args.forEach(function (arg) {
18+
t.test(arg, function (t) {
19+
try { fs.unlinkSync('file.txt') } catch (er) {}
20+
arg = arg.split(' ')
21+
var child = spawn(node, [run, '-c', ok].concat(arg))
22+
var gotStdout = false
23+
child.stdout.on('data', function (c) {
24+
gotStdout = true
25+
})
26+
child.stderr.on('data', function (c) {
27+
throw new Error('should not write to stderr')
28+
})
29+
child.on('close', function (code, sig) {
30+
t.equal(code, 0)
31+
t.equal(sig, null)
32+
t.ok(gotStdout, 'got standard output')
33+
t.match(fs.readFileSync('file.txt', 'utf8'), /^TAP version 13\n/)
34+
t.end()
35+
})
36+
})
37+
})
38+
39+
t.test('cleanup', function (t) {
40+
try { fs.unlinkSync('file.txt') } catch (er) {}
41+
t.done()
42+
})
43+

0 commit comments

Comments
 (0)