UNPKG

5.63 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3var Parser = require('../')
4var etoa = require('events-to-array')
5var util = require('util')
6
7var args = process.argv.slice(2)
8var json = null
9var flat = false
10var bail = false
11var preserveWhitespace = true
12var omitVersion = false
13var strict = false
14
15function version () {
16 console.log(require('../package.json').version)
17 process.exit(0)
18}
19
20for (let i = 0; i < args.length; i++) {
21 const arg = args[i]
22 if (arg === '-j') {
23 const val = +args[i + 1]
24 if (val >= 0) {
25 json = val
26 i += 1
27 } else
28 json = 2
29 continue
30 } else {
31 var m = arg.match(/^--json(?:=([0-9]+))?$/)
32 if (m) {
33 if (+m[1] >= 0)
34 json = +m[1]
35 else if (+args[i + 1] >= 0) {
36 json = +args[i + 1]
37 i += 1
38 } else
39 json = 2
40 continue
41 }
42 }
43
44 if (arg === '-v' || arg === '--version')
45 version()
46 else if (arg === '-o' || arg === '--omit-version')
47 omitVersion = true
48 else if (arg === '-w' || arg === '--ignore-all-whitespace')
49 preserveWhitespace = false
50 else if (arg === '-b' || arg === '--bail')
51 bail = true
52 else if (arg === '-B' || arg === '--no-bail')
53 bail = false
54 else if (arg === '-t' || arg === '--tap')
55 json = 'tap'
56 else if (arg === '-l' || arg === '--lines')
57 json = 'lines'
58 else if (arg === '-h' || arg === '--help')
59 usage()
60 else if (arg === '-f' || arg === '--flat')
61 flat = true
62 else if (arg === '-F' || arg === '--no-flat')
63 flat = false
64 else if (arg === '--strict')
65 strict = true
66 else if (arg === '--no-strict')
67 strict = false
68 else if (arg === '-s' || arg === '--silent')
69 json = 'silent'
70 else
71 console.error('Unrecognized arg: %j', arg)
72}
73
74function usage () {
75 console.log(`Usage:
76 tap-parser <options>
77
78Parses TAP data from stdin, and outputs the parsed result
79in the format specified by the options. Default output is
80uses node's \`util.inspect()\` method.
81
82Options:
83
84 -j [<indent>] | --json[=indent]
85 Output event data as JSON with the specified indentation (default=2)
86
87 -t | --tap
88 Output data as reconstituted TAP based on parsed results
89
90 -l | --lines
91 Output each parsed line as it is recognized by the parser
92
93 -b | --bail
94 Emit a \`Bail out!\` at the first failed test point encountered
95
96 -B | --no-bail
97 Do not bail out at the first failed test point encountered
98 (Default)
99
100 -f | --flat
101 Flatten all assertions to the top level parser
102
103 -F | --no-flat
104 Do not flatten all assertions to the top level parser
105 (Default)
106
107 -w | --ignore-all-whitespace
108 Skip over blank lines outside of YAML blocks
109
110 -o | --omit-version
111 Ignore the \`TAP version 13\` line at the start of tests
112
113 --strict
114 Run the parser in strict mode
115
116 --no-strict
117 Do not run the parser in strict mode
118
119 -s | --silent
120 Do not print output, just exit success/failure based on TAP stream
121`)
122
123 // prevent the EPIPE upstream when the data drops on the floor
124 /* istanbul ignore else */
125 if (!process.stdin.isTTY)
126 process.stdin.resume()
127
128 process.exit()
129}
130
131var yaml = require('tap-yaml')
132let id = 1
133function tapFormat (msg, indent) {
134 return indent + msg.map(function (item) {
135 switch (item[0]) {
136 case 'child':
137 var comment = item[1][0]
138 var child = item[1].slice(1)
139 return tapFormat([comment], '') + tapFormat(child, ' ')
140
141 case 'version':
142 return 'TAP version ' + item[1] + '\n'
143
144 case 'plan':
145 if (flat) {
146 item[1].start = 1
147 item[1].end = id - 1
148 }
149 var p = item[1].start + '..' + item[1].end
150 if (item[1].comment)
151 p += ' # ' + item[1].comment
152 return p + '\n'
153
154 case 'pragma':
155 return 'pragma ' + (item[2] ? '+' : '-') + item[1] + '\n'
156
157 case 'bailout':
158 var r = item[1] ? (' ' + item[1]) : ''
159 return 'Bail out!' + r + '\n'
160
161 case 'result':
162 case 'assert':
163 var res = item[1]
164 if (item[0] === 'result') {
165 res.id = id++
166 res.name = (res.fullname + ' > ' + (res.name || '')).trim()
167 }
168 return (res.ok ? '' : 'not ') + 'ok ' + res.id +
169 (res.name ? ' - ' + res.name.replace(/ \{$/, '') : '') +
170 (res.skip ? ' # SKIP' +
171 (res.skip === true ? '' : ' ' + res.skip) : '') +
172 (res.todo ? ' # TODO' +
173 (res.todo === true ? '' : ' ' + res.todo) : '') +
174 (res.time ? ' # time=' + res.time + 'ms' : '') +
175 '\n' +
176 (res.diag ?
177 ' ---\n ' +
178 yaml.stringify(res.diag).split('\n').join('\n ').trim() +
179 '\n ...\n'
180 : '')
181
182 case 'extra':
183 case 'comment':
184 return item[1]
185 }
186 }).join('').split('\n').join('\n' + indent).trim() + '\n'
187}
188
189function format (msg) {
190 if (json === 'tap')
191 return tapFormat(msg, '')
192 else if (json !== null)
193 return JSON.stringify(msg, null, +json)
194 else
195 return util.inspect(events, null, Infinity)
196}
197
198var options = {
199 bail: bail,
200 preserveWhitespace: preserveWhitespace,
201 omitVersion: omitVersion,
202 strict: strict,
203}
204
205var parser = new Parser(options)
206const ignore = [
207 'pipe',
208 'unpipe',
209 'prefinish',
210 'finish',
211 'line',
212 'pass',
213 'fail',
214 'todo',
215 'skip',
216]
217if (flat)
218 ignore.push('assert', 'child')
219else
220 ignore.push('result')
221
222var events = etoa(parser, ignore)
223
224if (json === 'lines')
225 parser.on('line', function (l) {
226 process.stdout.write(l)
227 })
228
229process.on('exit', function () {
230 if (json !== 'silent' && json !== 'lines')
231 console.log(format(events))
232 if (!parser.ok)
233 process.exit(1)
234})
235
236process.stdin.pipe(parser)