Commit d7828560 authored by Jérémy Lal's avatar Jérémy Lal

New upstream version 3.0.3

parents
.nyc_output
coverage
node_modules
sudo: false
language: node_js
node_js:
- '0.10'
- '4'
- '5'
- '6'
This software is released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#!/usr/bin/env node
var Parser = require('../')
var etoa = require('events-to-array')
var util = require('util')
var args = process.argv.slice(2)
var json = null
args.forEach(function (arg, i) {
if (arg === '-j') {
json = args[i + 1] || 2
} else {
var m = arg.match(/^--json(?:=([0-9]+))$/)
if (m)
json = +m[1] || args[i + 1] || 2
}
if (arg === '-t' || arg === '--tap')
json = 'tap'
if (arg === '-h' || arg === '--help')
usage()
})
function usage () {
console.log(function () {/*
Usage:
tap-parser [-j [<indent>] | --json[=indent] | -t | --tap]
Parses TAP data from stdin, and outputs an object representing
the data found in the TAP stream to stdout.
If there are any failures in the TAP stream, then exits with a
non-zero status code.
Data is output by default using node's `util.format()` method, but
JSON can be specified using the `-j` or `--json` flag with a number
of spaces to use as the indent (default=2).
If you pass -t or --tap as an argument, then the output will be a
re-imagined synthesized purified idealized manufactured TAP stream,
rather than JSON or util.format.
*/}.toString().split('\n').slice(1, -1).join('\n'))
if (!process.stdin.isTTY)
process.stdin.resume()
process.exit()
}
var yaml = require('js-yaml')
function tapFormat (msg, indent) {
return indent + msg.map(function (item) {
switch (item[0]) {
case 'child':
return tapFormat(item[1], ' ')
case 'version':
return 'TAP version ' + item[1] + '\n'
case 'plan':
var p = item[1].start + '..' + item[1].end
if (item[1].comment)
p += ' # ' + item[1].comment
return p + '\n'
case 'pragma':
return 'pragma ' + (item[2] ? '+' : '-') + item[1] + '\n'
case 'bailout':
var r = item[1] === true ? '' : (' ' + item[1])
return 'Bail out!' + r + '\n'
case 'assert':
var res = item[1]
return (res.ok ? '' : 'not ') + 'ok ' + res.id +
(res.name ? ' - ' + res.name : '') +
(res.skip ? ' # SKIP' +
(res.skip === true ? '' : ' ' + res.skip) : '') +
(res.todo ? ' # TODO' +
(res.todo === true ? '' : ' ' + res.todo) : '') +
(res.time ? ' # time=' + res.time + 's' : '') +
'\n' +
(res.diag ?
' ---\n ' +
yaml.safeDump(res.diag).split('\n').join('\n ').trim() +
'\n ...\n'
: '')
case 'extra':
case 'comment':
return item[1]
}
}).join('').split('\n').join('\n' + indent).trim() + '\n'
}
function format (msg) {
if (json === 'tap')
return tapFormat(msg, '')
else if (json !== null)
return JSON.stringify(msg, null, +json)
else
return util.inspect(events, null, Infinity)
}
var parser = new Parser()
var events = etoa(parser, [ 'pipe', 'unpipe', 'prefinish', 'finish', 'line' ])
process.stdin.pipe(parser)
process.on('exit', function () {
console.log(format(events))
if (!parser.ok)
process.exit(1)
})
usage: tap-parser OPTIONS
Parse TAP from INPUT. If there are any failures, exits with
a non-zero status code.
OPTIONS are:
-i, --input Read from INPUT. Default: stdin.
-o, --output Write to OUTPUT. Default: stdout.
-r, --results Print results as json. Otherwise pass INPUT
through to OUTPUT.
-h, --help Show this help message.
-v, --version Print the current version of tap-parser.
var parser = require('../');
var p = parser(function (results) {
console.dir(results);
});
process.stdin.pipe(p);
var test = require('tap').test;
test('beep', function (t) {
t.plan(2);
t.equal(2+2,4);
t.same({a:1,b:2},{a:1,b:1+1});
});
test('boop', function (t) {
t.plan(2);
t.equal(1+1,2);
setTimeout(function () {
t.ok(true);
}, 1000);
});
This diff is collapsed.
{
"name": "tap-parser",
"version": "3.0.3",
"description": "parse the test anything protocol",
"main": "index.js",
"bin": {
"tap-parser": "bin/cmd.js"
},
"dependencies": {
"events-to-array": "^1.0.1",
"js-yaml": "^3.2.7"
},
"devDependencies": {
"glob": "^7.0.5",
"tap": "^7.0.0"
},
"scripts": {
"test": "tap test/*.js --100",
"regen-fixtures": "node scripts/generate-test.js test/fixtures/*.tap"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/6..latest",
"chrome/10",
"chrome/latest",
"firefox/3.5",
"firefox/latest",
"opera/latest",
"safari/latest"
]
},
"repository": {
"type": "git",
"url": "git://github.com/substack/tap-parser.git"
},
"homepage": "https://github.com/substack/tap-parser",
"keywords": [
"tap",
"test",
"parser"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"license": "MIT",
"optionalDependencies": {
"readable-stream": "^2"
},
"files": [
"index.js",
"bin/cmd.js",
"bin/usage.txt"
]
}
# tap-parser
parse the [test anything protocol](http://testanything.org/)
[![build status](https://secure.travis-ci.org/tapjs/tap-parser.png)](http://travis-ci.org/tapjs/tap-parser)
[![browser support](http://ci.testling.com/substack/tap-parser.png)](http://ci.testling.com/substack/tap-parser)
[![coverage status](https://coveralls.io/repos/tapjs/tap-parser/badge.svg?branch=master&service=github)](https://coveralls.io/github/tapjs/tap-parser?branch=master)
# example
``` js
var parser = require('tap-parser');
var p = parser(function (results) {
console.dir(results);
});
process.stdin.pipe(p);
```
given some [TAP](http://testanything.org/)-formatted input:
```
$ node test.js
TAP version 13
# beep
ok 1 should be equal
ok 2 should be equivalent
# boop
ok 3 should be equal
ok 4 (unnamed assert)
1..4
# tests 4
# pass 4
# ok
```
parse the output:
```
$ node test.js | node parse.js
{ ok: true, count: 4, pass: 4, plan: { start: 1, end: 4 } }
```
# usage
This package also has a `tap-parser` command.
```
Usage:
tap-parser [-j [<indent>] | --json[=indent]]
Parses TAP data from stdin, and outputs an object representing
the data found in the TAP stream to stdout.
If there are any failures in the TAP stream, then exits with a
non-zero status code.
Data is output by default using node's `util.format()` method, but
JSON can be specified using the `-j` or `--json` flag with a number
of spaces to use as the indent (default=2).
```
# methods
``` js
var parser = require('tap-parser')
```
## var p = parser(options, cb)
Return a writable stream `p` that emits parse events.
If `cb` is given it will listen for the `'complete'` event.
If `options` is given, it may contain the following flags:
- `preserveWhitespace` boolean which is `false` by default and will
cause the parser to emit `line` events even for lines containing
only whitespace. (Whitespace lines in yaml blocks are always
emitted, because whitespace is semantically relevant for yaml.)
- `strict` boolean which is `false` by default and causes the parser
to treat non-TAP input as a failure. Strictness is heritable to
child subtests. You can also turn strictness on or off by using the
`pragma +strict` line in the TAP data to turn strictness on, or
`pragma -strict` to turn strictness off.
The `parent`, `level` and `buffered` options are reserved for internal
use.
# events
## p.on('complete', function (results) {})
The `results` object contains a summary of the number of tests
skipped, failed, passed, etc., as well as a boolean `ok` member which
is true if and only if the planned test were all found, and either
"ok" or marked as "TODO".
## p.on('assert', function (assert) {})
Every `/^(not )?ok\b/` line will emit an `'assert'` event.
Every `assert` object has these keys:
* `assert.ok` - true if the assertion succeeded, false if failed
* `assert.id` - the assertion number
* `assert.name` - optional short description of the assertion
and may also have
* `assert.todo` - optional description of why the assertion failure is
not a problem. (Boolean `true` if no explaination provided)
* `assert.skip` - optional description of why this assertion was
skipped (boolean `true` if no explanation provided)
* `assert.diag` - a diagnostic object with additional information
about the test point.
## p.on('comment', function (comment) {})
Every `/^# (.+)/` line will emit the string contents of `comment`.
## p.on('plan', function (plan) {})
Every `/^\d+\.\.\d+/` line emits a `'plan'` event for the test numbers
`plan.start` through `plan.end`, inclusive.
If the test is [completely
skipped](http://podwiki.hexten.net/TAP/TAP.html?page=TAP#Skippingeverything)
the result will look like
```
{ ok: true,
count: 0,
pass: 0,
plan:
{ start: 1,
end: 0,
skipAll: true,
skipReason: 'This code has no seat belt' } }
```
## p.on('version', function (version) {})
A `/^TAP version (\d+)/` line emits a `'version'` event with a version
number or string.
## p.on('bailout', function (reason) {})
A `bail out!` line will cause the parser to completely stop doing
anything. Child parser bailouts will bail out their parents as well.
## p.on('child', function (childParser) {})
If a child test set is embedded in the stream like this:
```
TAP Version 13
1..2
# nesting
1..2
ok 1 - true is ok
ok 2 - doag is also okay
ok 1 - nesting
ok 2 - second
```
then the child stream will be parsed and events will be raised on the
`childParser` object.
Since TAP streams with child tests *should* follow child test sets
with a pass or fail assert based on the child test's results, failing
to handle child tests should always result in the same end result.
However, additional information from those child tests will obviously
be lost.
## p.on('extra', function (extra) {})
All other lines will trigger an `'extra'` event with the line text.
# install
With [npm](https://npmjs.org) do:
```
npm install tap-parser
```
You can use [browserify](http://browserify.org) to `require('tap-parser')` in
the browser.
# license
MIT
#!/usr/bin/env node
var spawn = require('child_process').spawn
var path = require('path')
var fs = require('fs')
var etoa = require('events-to-array')
var Parser = require('../')
var util = require('util')
for (var i = 2; i < process.argv.length; i++) {
generate(process.argv[i])
}
function generate(file) {
file = path.resolve(file)
console.error(file)
var outfile = file.replace(/\.tap$/, '.json')
if (outfile === file)
throw new Error('incorrect file (should end in .tap) ' + file)
var output = ''
var p = new Parser()
fs.createReadStream(file, { encoding: 'utf8' }).pipe(p)
var events = etoa(p, [ 'pipe', 'unpipe', 'prefinish', 'finish' ])
p.on('complete', function () {
var f = JSON.stringify(events, null, 2) + '\n'
fs.writeFileSync(outfile, f)
})
}
var t = require('tap')
var Parser = require('../')
t.isa(Parser(), Parser, 'calling as function returns instance')
t.test('passing no options and cb works fine', function (t) {
var p = Parser(t.end)
p.emit('complete')
})
t.test('end() can take chunk', function (t) {
t.plan(2)
t.test('string', function (t) {
var p = Parser()
p.end('1..0\n', t.end)
})
t.test('encoding', function (t) {
var p = Parser()
p.end(new Buffer('1..0\n').toString('hex'), 'hex', t.end)
})
})
t.test('takes a buffer just fine', function (t) {
var p = Parser(theEnd)
p.write(new Buffer('TAP version 13\n'))
var calledme = false
function callme () {
calledme = true
}
var calledbail = false
function bailcall () {
calledbail = true
}
p.write('ok 1 i just met you\n')
p.write('ok and this is crazy\n')
p.write('ok 3 - but heres my number\n')
p.write('6f6b2034202d20736f2063616c6c206d65206d61796265', 'hex', callme)
p.write('Bail out! then call cb on next tick')
p.write('bailouts make all writes ignored right away', bailcall)
process.nextTick(function () {
p.end()
})
function theEnd (results) {
t.ok(calledme, 'called cb from normal write')
t.ok(calledbail, 'called cb from post-bailout write')
t.match(results, { ok: false, count: 4, pass: 4 })
t.end()
}
})
[
[
"line",
"1..5\n"
],
[
"plan",
{
"start": 1,
"end": 5
}
],
[
"line",
"ok 1\n"
],
[
"line",
"ok 2\n"
],
[
"assert",
{
"ok": true,
"id": 1
}
],
[
"line",
"ok 3\n"
],
[
"assert",
{
"ok": true,
"id": 2
}
],
[
"line",
"Bail out!\n"
],
[
"assert",
{
"ok": true,
"id": 3
}
],
[
"bailout",
""
],
[
"complete",
{
"ok": false,
"count": 3,
"pass": 3,
"bailout": true,
"plan": {
"start": 1,
"end": 5
},
"failures": []
}
]
]
1..5
ok 1
ok 2
ok 3
Bail out!
ok 4
ok 5
[
[
"line",
"1..5\n"
],
[
"plan",
{
"start": 1,
"end": 5
}
],
[
"line",
"ok 1\n"
],
[
"line",
"ok 2\n"
],
[
"assert",