tap-parser
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -5,4 +5,2 @@ var parser = require('../'); | ||
}); | ||
process.stdin.pipe(p); | ||
process.stdin.resume(); |
296
index.js
@@ -1,4 +0,3 @@ | ||
var Stream = require('stream'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var split = require('split'); | ||
var Writable = require('stream').Writable; | ||
var inherits = require('inherits'); | ||
@@ -17,15 +16,11 @@ var re = { | ||
function writable (s) { | ||
var stream = new Stream; | ||
stream.writable = true; | ||
stream.write = function (buf) { return s.write(buf) }; | ||
stream.end = function (buf) { return s.end(buf) }; | ||
return stream; | ||
} | ||
module.exports = Parser; | ||
inherits(Parser, Writable); | ||
module.exports = function (cb) { | ||
var sp = split(); | ||
var stream = writable(sp); | ||
function Parser (cb) { | ||
if (!(this instanceof Parser)) return new Parser(cb); | ||
Writable.call(this, { encoding: 'string' }); | ||
if (cb) this.on('results', cb); | ||
var results = stream.results = { | ||
this.results = { | ||
ok: undefined, | ||
@@ -38,152 +33,159 @@ asserts: [], | ||
}; | ||
this._lineNum = 1; | ||
this._line = ''; | ||
this._planMismatch = false; | ||
stream.on('assert', function (res) { | ||
results.asserts.push(res); | ||
if (!res.ok && !res.todo) results.ok = false; | ||
var dest = (res.ok ? results.pass : results.fail); | ||
if (res.todo) dest = results.todo; | ||
dest.push(res); | ||
var prev = results.asserts[results.asserts.length - 2]; | ||
if (prev && prev.number + 1 !== res.number) { | ||
stream.emit('parseError', { | ||
message: 'assert out of order' | ||
}); | ||
} | ||
this.on('finish', function () { | ||
if (this._line.length) this._online(this._line); | ||
this._finished(); | ||
}); | ||
stream.on('plan', function (plan, skip_reason) { | ||
if (results.plan !== undefined) { | ||
stream.emit('parseError', { | ||
message: 'unexpected additional plan', | ||
}); | ||
return; | ||
} | ||
if (plan.start === 1 && plan.end === 0) { | ||
plan.skip_all = true; | ||
plan.skip_reason = skip_reason; // could be undefined | ||
} else if (skip_reason) { | ||
stream.emit('parseError', { | ||
message: 'plan is not empty, but has a SKIP reason', | ||
skip_reason: skip_reason, | ||
}); | ||
plan.skip_all = false; | ||
plan.skip_reason = skip_reason; | ||
// continue to use the plan | ||
} | ||
results.plan = plan; | ||
checkAssertionStart(); | ||
this.on('assert', this._onassert); | ||
this.on('plan', this._onplan); | ||
this.on('parseError', function (err) { | ||
this.results.ok = false; | ||
err.line = this._lineNum; | ||
this.results.errors.push(err); | ||
}); | ||
} | ||
Parser.prototype._write = function (chunk, enc, next) { | ||
var parts = (this._line + chunk).split('\n'); | ||
for (var i = 0; i < parts.length - 1; i++) { | ||
this._online(parts[i]); | ||
this._lineNum ++; | ||
} | ||
this._line = parts[parts.length - 1]; | ||
next(); | ||
}; | ||
Parser.prototype._onassert = function (res) { | ||
var results = this.results; | ||
results.asserts.push(res); | ||
if (!res.ok && !res.todo) results.ok = false; | ||
var dest = (res.ok ? results.pass : results.fail); | ||
if (res.todo) dest = results.todo; | ||
dest.push(res); | ||
var planMismatch = false; | ||
function checkAssertionStart () { | ||
if (planMismatch) return; | ||
if (!results.asserts[0]) return; | ||
if (!results.plan) return; | ||
if (results.asserts[0].number === results.plan.start) return; | ||
planMismatch = true; | ||
stream.emit('parseError', { | ||
message: 'plan range mismatch' | ||
var prev = results.asserts[results.asserts.length - 2]; | ||
if (prev && prev.number + 1 !== res.number) { | ||
this.emit('parseError', { | ||
message: 'assert out of order' | ||
}); | ||
} | ||
}; | ||
Parser.prototype._onplan = function (plan, skip_reason) { | ||
var results = this.results; | ||
stream.on('parseError', function (err) { | ||
results.ok = false; | ||
err.line = lineNum; | ||
results.errors.push(err); | ||
}); | ||
var lineNum = 0; | ||
var ended = false; | ||
sp.on('data', ondata); | ||
sp.on('end', onend); | ||
sp.on('close', onend); | ||
if (cb) stream.on('results', cb); | ||
return stream; | ||
function onend () { | ||
if (ended) return; | ||
ended = true; | ||
if (results.plan !== undefined) { | ||
this.emit('parseError', { | ||
message: 'unexpected additional plan', | ||
}); | ||
return; | ||
} | ||
if (plan.start === 1 && plan.end === 0) { | ||
plan.skip_all = true; | ||
plan.skip_reason = skip_reason; // could be undefined | ||
} else if (skip_reason) { | ||
this.emit('parseError', { | ||
message: 'plan is not empty, but has a SKIP reason', | ||
skip_reason: skip_reason, | ||
}); | ||
plan.skip_all = false; | ||
plan.skip_reason = skip_reason; | ||
// continue to use the plan | ||
} | ||
results.plan = plan; | ||
this._checkAssertionStart(); | ||
}; | ||
Parser.prototype._online = function (line) { | ||
var m; | ||
if (m = re.version.exec(line)) { | ||
var ver = /^\d+(\.\d*)?$/.test(m[1]) ? Number(m[1]) : m[1]; | ||
this.emit('version', ver); | ||
} | ||
else if (m = re.comment.exec(line)) { | ||
this.emit('comment', m[1]); | ||
} | ||
else if (m = re.ok.exec(line)) { | ||
var ok = !m[1]; | ||
var num = m[2] && Number(m[2]); | ||
var name = m[3]; | ||
var asrt = { | ||
ok: ok, | ||
number: num, | ||
name: name | ||
}; | ||
if (results.plan === undefined) { | ||
stream.emit('parseError', { | ||
message: 'no plan found' | ||
if (num === undefined) { | ||
return this.emit('parseError', { | ||
message: 'assertion number not provided' | ||
}); | ||
} | ||
if (results.ok === undefined) results.ok = true; | ||
var skip_all = (results.plan && results.plan.skip_all); | ||
if (results.asserts.length === 0 && ! skip_all) { | ||
stream.emit('parseError', { | ||
message: 'no assertions found' | ||
}); | ||
} else if (skip_all && results.asserts.length !== 0) { | ||
stream.emit('parseError', { | ||
message: 'assertion found after skip_all plan' | ||
}); | ||
if (m = re.label_todo.exec(name)) { | ||
asrt.name = m[1]; | ||
asrt.todo = m[2]; | ||
} | ||
var last = results.asserts.length | ||
&& results.asserts[results.asserts.length - 1].number | ||
; | ||
if (results.ok && last < results.plan.end) { | ||
stream.emit('parseError', { | ||
message: 'not enough asserts' | ||
}); | ||
} | ||
else if (results.ok && last > results.plan.end) { | ||
stream.emit('parseError', { | ||
message: 'too many asserts' | ||
}); | ||
} | ||
stream.emit('results', results); | ||
this.emit('assert', asrt); | ||
} | ||
else if (m = re.plan.exec(line)) { | ||
this.emit('plan', { | ||
start: Number(m[1]), | ||
end: Number(m[2]), | ||
}, | ||
m[3]); // reason, if SKIP | ||
} | ||
}; | ||
Parser.prototype._checkAssertionStart = function () { | ||
var results = this.results; | ||
if (this._planMismatch) return; | ||
if (!results.asserts[0]) return; | ||
if (!results.plan) return; | ||
if (results.asserts[0].number === results.plan.start) return; | ||
function ondata (line) { | ||
var m; | ||
lineNum ++; | ||
if (m = re.version.exec(line)) { | ||
var ver = /^\d+(\.\d*)?$/.test(m[1]) ? Number(m[1]) : m[1]; | ||
stream.emit('version', ver); | ||
} | ||
else if (m = re.comment.exec(line)) { | ||
stream.emit('comment', m[1]); | ||
} | ||
else if (m = re.ok.exec(line)) { | ||
var ok = !m[1]; | ||
var num = m[2] && Number(m[2]); | ||
var name = m[3]; | ||
var asrt = { | ||
ok: ok, | ||
number: num, | ||
name: name | ||
}; | ||
if (num === undefined) { | ||
return stream.emit('parseError', { | ||
message: 'assertion number not provided' | ||
}); | ||
} | ||
if (m = re.label_todo.exec(name)) { | ||
asrt.name = m[1]; | ||
asrt.todo = m[2]; | ||
} | ||
stream.emit('assert', asrt); | ||
} | ||
else if (m = re.plan.exec(line)) { | ||
stream.emit('plan', { | ||
start: Number(m[1]), | ||
end: Number(m[2]), | ||
}, | ||
m[3]); // reason, if SKIP | ||
} | ||
this._planMismatch = true; | ||
this.emit('parseError', { | ||
message: 'plan range mismatch' | ||
}); | ||
}; | ||
Parser.prototype._finished = function () { | ||
var results = this.results; | ||
if (results.plan === undefined) { | ||
this.emit('parseError', { | ||
message: 'no plan found' | ||
}); | ||
} | ||
if (results.ok === undefined) results.ok = true; | ||
var skip_all = (results.plan && results.plan.skip_all); | ||
if (results.asserts.length === 0 && ! skip_all) { | ||
this.emit('parseError', { | ||
message: 'no assertions found' | ||
}); | ||
} else if (skip_all && results.asserts.length !== 0) { | ||
this.emit('parseError', { | ||
message: 'assertion found after skip_all plan' | ||
}); | ||
} | ||
var last = results.asserts.length | ||
&& results.asserts[results.asserts.length - 1].number | ||
; | ||
if (results.ok && last < results.plan.end) { | ||
this.emit('parseError', { | ||
message: 'not enough asserts' | ||
}); | ||
} | ||
else if (results.ok && last > results.plan.end) { | ||
this.emit('parseError', { | ||
message: 'too many asserts' | ||
}); | ||
} | ||
this.emit('results', results); | ||
}; |
{ | ||
"name" : "tap-parser", | ||
"version" : "0.2.1", | ||
"description" : "parse the test anything protocol", | ||
"main" : "index.js", | ||
"dependencies" : { | ||
"split" : "~0.1.2" | ||
}, | ||
"devDependencies" : { | ||
"tap" : "~0.4.6", | ||
"tape" : "~2.3.0" | ||
}, | ||
"scripts" : { | ||
"test" : "tap test/*.js" | ||
}, | ||
"testling" : { | ||
"files" : "test/*.js", | ||
"browsers" : [ | ||
"ie/8", "ie/9", | ||
"chrome/23", "firefox/17", | ||
"opera/12", "safari/5.1" | ||
] | ||
}, | ||
"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" | ||
"name": "tap-parser", | ||
"version": "0.3.0", | ||
"description": "parse the test anything protocol", | ||
"main": "index.js", | ||
"dependencies": { | ||
"inherits": "~2.0.1" | ||
}, | ||
"devDependencies": { | ||
"tape": "~2.3.2", | ||
"tap": "~0.4.6" | ||
}, | ||
"scripts": { | ||
"test": "tap test/*.js" | ||
}, | ||
"testling": { | ||
"files": "test/*.js", | ||
"browsers": [ | ||
"ie/8..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" | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
913
30331
+ Addedinherits@~2.0.1
+ Addedinherits@2.0.4(transitive)
- Removedsplit@~0.1.2
- Removedsplit@0.1.2(transitive)
- Removedthrough@1.1.2(transitive)