A highly verbose parser for the Test Anything Protocol that exposes an observable and streaming interface
npm install @tap-format/parser
A highly verbose parser for the Test Anything Protocol that exposes an observable and streaming interface.
This is the parser used to create the following beautiful TAP formatters:
* @tap-format/spec - Formatted TAP output the like the Mocha spec reporter
* @tap-format/dot - Formatted TAP output with dots ...
* @tap-format/failures - Formatted output for TAP assertion failures with diffs
* @tap-format/results - Formatted output for TAP runner results
* 0.10
* 0.12
* iojs
* >= 4.x
```
npm install @tap-format/parser --save
The parser exposes an interface that lets you deal with the parsed TAP with Reactive Extensions. See the [API]() section for a full list of exposed Observables.
`js
var parse = require('@tap-format/parser')
var stream = process.stdin
var tap$ = parser.observeStream(stream)
tap$.tests$
.forEach(function (test) {
console.log(test.title)
})
tap$.asserions$
.forEach(function (assertion) {
console.log(assertion.title)
})
`
The parser will parse streaming data for any source.
`js
var parser = require('@tap-format/parser')
var H = require('highland')
var tapStream = H(process.stdin.pipe(parser.stream()))
var tests = tapStream.filter(function (line) {
return line.type === 'test'
})
var assertions = tapStream.filter(function (line) {
return line.type === 'assertion'
})
tests.each(function (test) {
console.log(test.title)
})
assertions.each(function (assertion) {
console.log(assertion.title)
})
`
``
$ something-that-produces-tap | tap-format-parser
{
// Parsed TAP output as JSON here
}
Given a streaming input, the parser will expose and RXjs Observable chunked by new lines. In addition, the parser exposes the following properties as Observables as convenience methods for the parsed TAP.
`js
var parser = requrie('@tap-format/parser')
var stream = process.stdin
var tap$ = parser.observeStream(stream)
`
*
#### tap$
An Observable of all parsed output for the given input TAP stream
`js`
// This will console.log every assertion title
tap$
.filter(function (line) {
return line.type === 'assertion'
})
.forEach(function (assertion) {
console.log(assertion.title)
})
*
#### tap$.tests$
An Observable of all parsed tests.
`js`
// This will console.log all test titles
tap$.tests$
.map(function (test) {
return 'TEST: ' + test.title
})
.forEach(console.log.bind(console))
The shape of the test object is as follows:
* raw - the raw test line TAP from the TAP input (i.e. # My Test)test
* type - the type of the line. This will always be # My Test
* title - the parsed test title. becomes My Test
* lineNumber - the line number of the TAP input
* testNumber - the test number from the TAP input
*
#### tap$.assertions$
An Observable of all parsed assertions.
`js`
// This will console.log all assertion titles
tap$.assertions$
.map(function (assertion) {
return (assertion.ok ? 'OK: ' : 'NOT OK: ') + assertion
})
.forEach(console.log.bind(console))
The shape of the assertion object is as follows:
* raw - the raw test line TAP output, including any diagnostic associated with it
* type - the type of the line. This will always be assertiontrue/false
* title - the parsed test title, excluding any diagnostic associated with it
* ok - - indicates whether the assertion passed or failednot ok
* diagnostic - an object of any diagnostic associated with the assertion. If the assertion is , this will be information about the expected and actual values, etc. The TAP input will be YAML, but this value will always be an object
* rawDiagnostic - the raw diagnostic fromt he TAP input
* assertionNumber - the assertion number from the TAP input
* lineNumber - the line number of the TAP input
* testNumber - the test number that the assertion is within from the TAP input
*
#### tap$.comments$
An Observable of all output that is not tap. The parser assumes these are from console.log() and treats them as comments.
`js`
// This will console.log all the comment titles
tap$.comments$
.map(function (comment) {
return 'COMMENT: ' + comment.title
})
.forEach(console.log.bind(console))
The shape of the comment object is as follows:
* raw - the raw comment line from the TAP input
* type - the type of the line. This will always be comment
* title - the parsed comment title
* lineNumber - the line number of the TAP input
*
#### tap$.results$
An Observable of the parsed TAP results. This will only ever be of type tests, pass, or fail.
`js`
// This will console.log the names and counts of the results
tap$.results$
.forEach(function (result) {
console.log(result.name + ' ' + result.count)
})
The shape of the result object is as follows:
* raw - the raw result line from the TAP input (i.e. # pass 3)result
* type - the type of the line. This will always be
* name - the name of the result (i.e. pass, fail, assertions, etc.)
* count - the number of assertions associated with this result
*
#### tap$.plans$
An Observable of all parsed plans given from TAP output. This is usually only one item.
`js`
// This will console.log the 'from' and 'to' from the plan
tap$.plans$
.forEach(function (plan) {
console.log('FROM: ' + plan.from')
console.log('TO: ' + plan.to')
})
The shape of the plan object is as follows:
* raw - the raw plan line TAP output (i.e. 1..7)plan
* type - the type of the line. This will always be 1
* from - this will almost always be
* to - the total number of assertions from the TAP input
* skip - the number of assertions skipped
*
#### tap$.versions$
An Observable of the parsed TAP version
`js`
// This will console.log the TAP version
tap$.versions$
.forEach(function (version) {
console.log(version.raw)
})
The shape of the version object is as follows:
* raw - the raw version line TAP output (i.e. TAP version 13)version
* type - the type of the line. This will always be
*
Using require('@tap-format/parser').stream() returns a new-line-chunked stream of parsed TAP. It is a normal stream, and therefore exposes the very useful pipe() method.
```
git clone git@github.com:scottcorgan/tap-out.git .
npm install
npm test