dot.dot.dot.exampol

This commit is contained in:
Captain Nick Lucifer* 2023-03-10 23:21:16 +05:45
commit a0bc2d79de
406 changed files with 34577 additions and 0 deletions

16
node_modules/tap/lib/main.js generated vendored Normal file
View file

@ -0,0 +1,16 @@
var GlobalHarness = require("./tap-global-harness")
// this lets you do stuff like:
// var test = require("tap").test
// test(...)
// to run stuff in the global harness.
exports = module.exports = new GlobalHarness()
exports.createProducer = exports.Producer = require("./tap-producer")
exports.createConsumer = exports.Consumer = require("./tap-consumer")
exports.yamlish = require("yamlish")
exports.createTest = exports.Test = require("./tap-test")
exports.createHarness = exports.Harness = require("./tap-harness")
exports.createRunner = exports.Runner = require("./tap-runner")
exports.assert = require("./tap-assert")

442
node_modules/tap/lib/tap-assert.js generated vendored Normal file
View file

@ -0,0 +1,442 @@
// an assert module that returns tappable data for each assertion.
var difflet = require('difflet')
, deepEqual = require('deep-equal')
, bufferEqual = require('buffer-equal')
module.exports = assert
var syns = {}
, id = 1
function assert (ok, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
//console.error("assert %j", [ok, message, extra])
//if (extra && extra.skip) return assert.skip(message, extra)
//console.error("assert", [ok, message, extra])
ok = !!ok
var res = { id : id ++, ok: ok }
var caller = getCaller(extra && extra.error)
if (extra && extra.error) {
res.type = extra.error.name
res.message = extra.error.message
res.code = extra.error.code
|| extra.error.type
res.errno = extra.error.errno
delete extra.error
}
if (caller.file) {
res.file = caller.file
res.line = +caller.line
res.column = +caller.column
}
res.stack = caller.stack
res.name = message || "(unnamed assert)"
if (extra) Object.keys(extra).forEach(function (k) {
if (!res.hasOwnProperty(k)) res[k] = extra[k]
})
// strings and objects are hard to diff by eye
if (!ok &&
res.hasOwnProperty("found") &&
res.hasOwnProperty("wanted") &&
res.found !== res.wanted) {
if (typeof res.wanted !== typeof res.found ||
typeof res.wanted === "object" && (!res.found || !res.wanted)) {
res.type = { found: typeof found
, wanted: typeof wanted }
} else if (typeof res.wanted === "string") {
res.diff = diffString(res.found, res.wanted)
} else if (typeof res.wanted === "object") {
res.diff = diffObject(res.found, res.wanted)
}
}
//console.error("assert return", res)
return res
}
assert.ok = assert
syns.ok = [ "true", "assert" ]
function notOk (ok, message, extra) {
return assert(!ok, message, extra)
}
assert.notOk = notOk
syns.notOk = [ "false", "notok" ]
function error (er, message, extra) {
if (!er) {
// just like notOk(er)
return assert(!er, message, extra)
}
message = message || er.message
extra = extra || {}
extra.error = er
return assert.fail(message, extra)
}
assert.error = error
syns.error = [ "ifError", "ifErr", "iferror" ]
function pass (message, extra) {
return assert(true, message, extra)
}
assert.pass = pass
function fail (message, extra) {
//console.error("assert.fail", [message, extra])
//if (extra && extra.skip) return assert.skip(message, extra)
return assert(false, message, extra)
}
assert.fail = fail
function skip (message, extra) {
//console.error("assert.skip", message, extra)
if (!extra) extra = {}
return { id: id ++, skip: true, name: message || "" }
}
assert.skip = skip
function throws (fn, wanted, message, extra) {
if (typeof wanted === "string") {
extra = message
message = wanted
wanted = null
}
if (extra && extra.skip) return assert.skip(message, extra)
var found = null
try {
fn()
} catch (e) {
found = { name: e.name, message: e.message }
}
extra = extra || {}
extra.found = found
if (wanted) {
wanted = { name: wanted.name, message: wanted.message }
extra.wanted = wanted
}
if (!message) {
message = "Expected to throw"
if (wanted) message += ": "+wanted.name + " " + wanted.message
}
return (wanted) ? assert.similar(found, wanted, message, extra)
: assert.ok(found, message, extra)
}
assert.throws = throws
function doesNotThrow (fn, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
var found = null
try {
fn()
} catch (e) {
found = {name: e.name, message: e.message}
}
message = message || "Should not throw"
return assert.equal(found, null, message, extra)
}
assert.doesNotThrow = doesNotThrow
function equal (a, b, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
extra = extra || {}
message = message || "should be equal"
extra.found = a
extra.wanted = b
return assert(a === b, message, extra)
}
assert.equal = equal
syns.equal = ["equals"
,"isEqual"
,"is"
,"strictEqual"
,"strictEquals"]
function equivalent (a, b, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
var extra = extra || {}
message = message || "should be equivalent"
extra.found = a
extra.wanted = b
if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {
return assert(bufferEqual(a, b), message, extra)
} else {
return assert(deepEqual(a, b), message, extra)
}
}
assert.equivalent = equivalent
syns.equivalent = ["isEquivalent"
,"looseEqual"
,"looseEquals"
,"isDeeply"
,"same"
,"deepEqual"
,"deepEquals"]
function inequal (a, b, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
extra = extra || {}
message = message || "should not be equal"
extra.found = a
extra.doNotWant = b
return assert(a !== b, message, extra)
}
assert.inequal = inequal
syns.inequal = ["notEqual"
,"notEquals"
,"isNotEqual"
,"isNot"
,"not"
,"doesNotEqual"
,"isInequal"]
function inequivalent (a, b, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
extra = extra || {}
message = message || "should not be equivalent"
extra.found = a
extra.doNotWant = b
if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {
return assert(!bufferEqual(a, b), message, extra)
} else {
return assert(!deepEqual(a, b), message, extra)
}
}
assert.inequivalent = inequivalent
syns.inequivalent = ["notEquivalent"
,"notDeepEqual"
,"notDeeply"
,"notSame"
,"isNotDeepEqual"
,"isNotDeeply"
,"isNotEquivalent"
,"isInequivalent"]
function similar (a, b, message, extra, flip) {
if (extra && extra.skip) return assert.skip(message, extra)
// test that a has all the fields in b
message = message || "should be similar"
if (typeof a === "string" &&
(Object.prototype.toString.call(b) === "[object RegExp]")) {
extra = extra || {}
extra.pattern = b
extra.string = a
var ok = a.match(b)
extra.match = ok
if (flip) ok = !ok
return assert.ok(ok, message, extra)
}
var isObj = assert(a && typeof a === "object", message, extra)
if (!isObj.ok) {
// not an object
if (a == b) isObj.ok = true
if (flip) isObj.ok = !isObj.ok
return isObj
}
var eq = flip ? inequivalent : equivalent
return eq(selectFields(a, b), b, message, extra)
}
assert.similar = similar
syns.similar = ["isSimilar"
,"has"
,"hasFields"
,"like"
,"isLike"]
function dissimilar (a, b, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
message = message || "should be dissimilar"
return similar(a, b, message, extra, true)
}
assert.dissimilar = dissimilar
syns.dissimilar = ["unsimilar"
,"notSimilar"
,"unlike"
,"isUnlike"
,"notLike"
,"isNotLike"
,"doesNotHave"
,"isNotSimilar"
,"isDissimilar"]
function type (thing, t, message, extra) {
if (extra && extra.skip) return assert.skip(message, extra)
var name = t
if (typeof name === "function") name = name.name || "(anonymous ctor)"
//console.error("name=%s", name)
message = message || "type is "+name
var type = typeof thing
//console.error("type=%s", type)
if (!thing && type === "object") type = "null"
if (type === "object" && t !== "object") {
if (typeof t === "function") {
//console.error("it is a function!")
extra = extra || {}
extra.found = Object.getPrototypeOf(thing).constructor.name
extra.wanted = name
//console.error(thing instanceof t, name)
return assert.ok(thing instanceof t, message, extra)
}
//console.error("check prototype chain")
// check against classnames or objects in prototype chain, as well.
// type(new Error("asdf"), "Error")
// type(Object.create(foo), foo)
var p = thing
while (p = Object.getPrototypeOf(p)) {
if (p === t || p.constructor && p.constructor.name === t) {
type = name
break
}
}
}
//console.error(type, name, type === name)
return assert.equal(type, name, message, extra)
}
assert.type = type
syns.type = ["isa"]
// synonyms are helpful.
Object.keys(syns).forEach(function (c) {
syns[c].forEach(function (s) {
Object.defineProperty(assert, s, { value: assert[c], enumerable: false })
})
})
// helpers below
function selectFields (a, b) {
// get the values in A of the fields in B
var ret = Array.isArray(b) ? [] : {}
Object.keys(b).forEach(function (k) {
if (!a.hasOwnProperty(k)) return
var v = b[k]
, av = a[k]
if (v && av && typeof v === "object" && typeof av === "object"
&& !(v instanceof Date)
&& !(v instanceof RegExp)
&& !(v instanceof String)
&& !(v instanceof Boolean)
&& !(v instanceof Number)
&& !(Array.isArray(v))) {
ret[k] = selectFields(av, v)
} else ret[k] = av
})
return ret
}
function sortObject (obj) {
if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) {
return obj
}
return Object.keys(obj).sort().reduce(function (acc, key) {
acc[key] = sortObject(obj[key])
return acc
}, {})
}
function stringify (a) {
return JSON.stringify(sortObject(a), (function () {
var seen = []
, keys = []
return function (key, val) {
var s = seen.indexOf(val)
if (s !== -1) {
return "[Circular: "+keys[s]+"]"
}
if (val && typeof val === "object" || typeof val === "function") {
seen.push(val)
keys.push(val["!"] || val.name || key || "<root>")
if (typeof val === "function") {
return val.toString().split(/\n/)[0]
} else if (typeof val.toUTCString === "function") {
return val.toUTCString()
}
}
return val
}})())
}
function diffString (f, w) {
if (w === f) return null
var p = 0
, l = w.length
while (p < l && w.charAt(p) === f.charAt(p)) p ++
w = stringify(w).substr(1).replace(/"$/, "")
f = stringify(f).substr(1).replace(/"$/, "")
return diff(f, w, p)
}
function diffObject (f, w) {
return difflet({ indent : 2, comment : true }).compare(w, f)
}
function diff (f, w, p) {
if (w === f) return null
var i = p || 0 // it's going to be at least p. JSON can only be bigger.
, l = w.length
while (i < l && w.charAt(i) === f.charAt(i)) i ++
var pos = Math.max(0, i - 20)
w = w.substr(pos, 40)
f = f.substr(pos, 40)
var pointer = i - pos
return "FOUND: "+f+"\n"
+ "WANTED: "+w+"\n"
+ (new Array(pointer + 9).join(" "))
+ "^ (at position = "+p+")"
}
function getCaller (er) {
// get the first file/line that isn't this file.
if (!er) er = new Error
var stack = er.stack || ""
stack = stack.split(/\n/)
for (var i = 1, l = stack.length; i < l; i ++) {
var s = stack[i].match(/\(([^):]+):([0-9]+):([0-9]+)\)$/)
if (!s) continue
var file = s[1]
, line = +s[2]
, col = +s[3]
if (file.indexOf(__dirname) === 0) continue
if (file.match(/tap-test\/test.js$/)) continue
else break
}
var res = {}
if (file && file !== __filename && !file.match(/tap-test\/test.js$/)) {
res.file = file
res.line = line
res.column = col
}
res.stack = stack.slice(1).map(function (s) {
return s.replace(/^\s*at\s*/, "")
})
return res
}

63
node_modules/tap/lib/tap-browser-harness.js generated vendored Normal file
View file

@ -0,0 +1,63 @@
// this is just a harness that pipes to stdout.
// It's the default one.
module.exports = BrowserHarness
var BrowserHarness = global.TAP_Browser_Harness
, inherits = require("inherits")
, Results = require("./tap-results")
, Harness = require("./tap-harness")
, Test = require("./tap-test")
inherits(BrowserHarness, Harness)
function BrowserHarness (outPipe) {
//console.error("calling BrowserHarness")
if (browserHarness) return browserHarness
if (!(this instanceof BrowserHarness)) {
return browserHarness = new BrowserHarness
}
browserHarness = global.TAP_Browser_Harness = this
BrowserHarness.super.call(this, Test)
if (outPipe) this.output.pipe(outPipe)
this.test = this.test.bind(this)
this.plan = this.plan.bind(this)
var output = this.output
this.on("childEnd", function (child) {
//console.error("childEnd in global harness")
//console.error(child.results)
// write out the stuff for this child.
//console.error("child.conf", child.conf)
output.write(child.conf.name || "(unnamed test)")
// maybe write some other stuff about the number of tests in this
// thing, etc. I dunno.
//console.error("child results", child.results)
this.results.list.forEach(function (res) {
//delete res.error
//console.error("child resuilt", res)
output.write(res)
})
//console.error("wrote child results")
this.results.list.length = 0
})
var streamEnded = false
this.on("end", function () {
//console.error("global ending the stream")
if (!streamEnded) {
this.results.list.forEach(function (res) {
output.write(res)
})
this.results.list.length = 0
output.end()
streamEnded = true
}
})
// TODO: handle global errors
// process.on("unhandledException", function (e) {
// this.bailout("unhandled exception: " + e.message)
// })
}

243
node_modules/tap/lib/tap-consumer.js generated vendored Normal file
View file

@ -0,0 +1,243 @@
module.exports = TapConsumer
// pipe a stream into this that's emitting tap-formatted data,
// and it'll emit "data" events with test objects or comment strings
// and an "end" event with the final results.
var yamlish = require("yamlish")
, Results = require("./tap-results")
, inherits = require("inherits")
TapConsumer.decode = TapConsumer.parse = function (str) {
var tc = new TapConsumer
, list = []
tc.on("data", function (res) {
list.push(res)
})
tc.end(str)
tc.results.list = list
return tc.results
}
inherits(TapConsumer, require("stream").Stream)
function TapConsumer () {
if (!(this instanceof TapConsumer)) {
return new TapConsumer
}
TapConsumer.super.call(this)
this.results = new Results
this.readable = this.writable = true
this.on("data", function (res) {
if (typeof res === "object") this.results.add(res)
})
this._plan = null
this._buffer = ""
this._indent = []
this._current = null
this._actualCount = 0
this._passed = []
this._failed = []
//console.error("TapConsumer ctor done")
}
TapConsumer.prototype.bailedOut = false
TapConsumer.prototype.write = function (chunk) {
if (!this.writable) this.emit("error", new Error("not writable"))
if (this.bailedOut) return true
this._buffer = this._buffer + chunk
// split it up into lines.
var lines = this._buffer.split(/\r?\n/)
// ignore the last line, since it might be incomplete.
this._buffer = lines.pop()
for (var i = 0, l = lines.length; i < l; i ++) {
//console.error([i, lines[i]])
// see if it's indented.
var line = lines[i]
, spaces = (this._indent.length && !line.trim())
|| line.match(/^\s/)
// at this level, only interested in fully undented stuff.
if (spaces) {
var c = i
while (c < l && (!lines[c].trim() || lines[c].match(/^\s/))) {
this._indent.push(lines[c++])
}
//console.error(c-i, "indented", this._indent, this._current)
i = c - 1
continue
}
// some kind of line. summary, ok, notok, comment, or garbage.
// this also finishes parsing any of the indented lines from before
this._parseLine(line)
}
return true
}
TapConsumer.prototype.end = function () {
// finish up any hanging indented sections or final buffer
if (this._buffer.match(/^\s/)) this._indent.push(this.buffer)
else this._parseLine(this._buffer)
if (!this.bailedOut &&
this._plan !== null &&
this.results.testsTotal !== this._plan) {
while (this._actualCount < this._plan) {
this.emit("data", {ok: false, name:"MISSING TEST",
id:this._actualCount ++ })
}
}
this._parseLine("")
this._buffer = ""
this.writable = false
this.emit("end", null, this._actualCount, this._passed)
}
TapConsumer.prototype._parseLine = function (line) {
if (this.bailedOut) return
//console.error("_parseLine", [line])
// if there are any indented lines, and there is a
// current object already, then they belong to it.
// if there is not a current object, then they're garbage.
if (this._current && this._indent.length) {
this._parseIndented()
}
this._indent.length = 0
if (this._current) {
if (this._current.ok) this._passed.push(this._current.id)
else this._failed.push(this._current.id)
this.emit("data", this._current)
}
this._current = null
line = line.trim()
if (!line) return
// try to see what kind of line this is.
var bo
if (bo = line.match(/^bail out!\s*(.*)$/i)) {
this.bailedOut = true
// this.emit("error", new Error(line))
this.emit("bailout", bo[1])
return
}
if (line.match(/^#/)) { // just a comment
line = line.replace(/^#+/, "").trim()
// console.error("outputting comment", [line])
if (line) this.emit("data", line)
return
}
var plan = line.match(/^([0-9]+)\.\.([0-9]+)(?:\s+#(.*))?$/)
if (plan) {
var start = +(plan[1])
, end = +(plan[2])
, comment = plan[3]
// TODO: maybe do something else with this?
// it might be something like: "1..0 #Skip because of reasons"
this._plan = end
this.emit("plan", end, comment)
// plan must come before or after all tests.
if (this._actualCount !== 0) {
this._sawPlan = true
}
return
}
if (line.match(/^(not )?ok(?:\s+([0-9]+))?/)) {
this._parseResultLine(line)
return
}
// garbage. emit as a comment.
//console.error("emitting", [line.trim()])
if (line.trim()) this.emit("data", line.trim())
}
TapConsumer.prototype._parseDirective = function (line) {
line = line.trim()
if (line.match(/^TODO\b/i)) {
return { todo:true, explanation: line.replace(/^TODO\s*/i, "") }
} else if (line.match(/^SKIP\b/i)) {
return { skip:true, explanation: line.replace(/^SKIP\s*/i, "") }
}
}
TapConsumer.prototype._parseResultLine = function (line) {
this._actualCount ++
if (this._sawPlan) {
this.emit("data", {ok: false, name:"plan in the middle of tests"
,id:this._actualCount ++})
}
var parsed = line.match(/^(not )?ok(?: ([0-9]+))?(?:(?: - )?(.*))?$/)
, ok = !parsed[1]
, id = +(parsed[2] || this._actualCount)
, rest = parsed[3] || ""
, name
, res = { id:id, ok:ok }
// split on un-escaped # characters
//console.log("# "+JSON.stringify([name, rest]))
rest = rest.replace(/([^\\])((?:\\\\)*)#/g, "$1\n$2").split("\n")
name = rest.shift()
rest = rest.filter(function (r) { return r.trim() }).join("#")
//console.log("# "+JSON.stringify([name, rest]))
// now, let's see if there's a directive in there.
var dir = this._parseDirective(rest.trim())
if (!dir) name += rest ? "#" + rest : ""
else {
res.ok = true
if (dir.skip) res.skip = true
else if (dir.todo) res.todo = true
if (dir.explanation) res.explanation = dir.explanation
}
res.name = name
//console.error(line, [ok, id, name])
this._current = res
}
TapConsumer.prototype._parseIndented = function () {
// pull yamlish block out
var ind = this._indent
, ys
, ye
, yind
, diag
//console.error(ind, this._indent)
for (var i = 0, l = ind.length; i < l; i ++) {
var line = ind[i]
, lt = line.trim()
if (!ys) {
ys = line.match(/^(\s*)---(.*)$/)
if (ys) {
yind = ys[1]
diag = [ys[2]]
//console.error([line,ys, diag])
continue
} else if (lt) this.emit("data", lt)
} else if (ys && !ye) {
if (line === yind + "...") ye = true
else {
diag.push(line.substr(yind.length))
}
} else if (ys && ye && lt) this.emit("data", lt)
}
if (diag) {
//console.error('about to parse', diag)
diag = yamlish.decode(diag.join("\n"))
//console.error('parsed', diag)
Object.keys(diag).forEach(function (k) {
//console.error(this._current, k)
if (!this._current.hasOwnProperty(k)) this._current[k] = diag[k]
}, this)
}
}

78
node_modules/tap/lib/tap-cov-html.js generated vendored Normal file
View file

@ -0,0 +1,78 @@
var fs = require('fs'),
path = require('path'),
asyncMap = require("slide").asyncMap,
util = require('util');
var CovHtml = module.exports = function(cov_stats, cov_dir, cb) {
var index = [];
asyncMap(
Object.keys(cov_stats),
function(f, cb) {
var st = cov_stats[f],
missing_lines = st.missing.map(function(l) {
return l.number;
}),
out = '<!doctype html>\n<html lang="en">\n<head>\n ' +
'<meta charset="utf-8">\n <title>' +
f + ' (' + st.loc + ')</title>\n' +
'<style type="text/css">\n' +
'li {\n' +
' font-family: monospace;\n' +
' white-space: pre;\n' +
'}\n' +
'</style>\n' +
'</head>\n<body>\n' +
'<h1>' + f + ' (' + st.loc + ')' + '</h1>' +
'<h2>Run: ' + (st.missing.length ? st.loc - st.missing.length : st.loc) + ', Missing: ' +
st.missing.length + ', Percentage: ' + st.percentage + '</h2>' +
'<h2>Source:</h2>\n' +
'<ol>\n' +
st.lines.map(function(line) {
var number = line.number,
color = (missing_lines.indexOf(number) !== -1) ? '#fcc' : '#cfc';
return '<li id="L' + line.number + '" style="background-color: ' + color +
';">' + line.source.replace(/</g, "&lt;") + '</li>';
}).join('\n') +
'</ol>\n' +
'<h2>Data</h2>\n'+
'<pre>' + util.inspect(st, true, Infinity, false).replace(/</g, "&lt;") + '</pre></body>\n</html>';
fs.writeFile(
cov_dir + '/' +
f.replace(process.cwd() + '/', '').replace(/\//g, '+') + '.html',
out,
'utf8',
function(err) {
if (err) {
throw err;
}
index.push(f);
cb();
});
},
function(err) {
if (err) {
throw err;
}
var out = '<!doctype html>\n<html lang="en">\n<head>\n ' +
'<meta charset="utf-8">\n <title>Coverage Index</title>\n</head>\n' +
'<body>\n<h1>Code Coverage Information</h1>\n<ul>' +
index.map(function(fname) {
return '<li><a href="' +
fname.replace(process.cwd() + '/', '').replace(/\//g, '+') + '.html' +
'">' + fname + '</a></li>';
}).join('\n') + '</ul>\n</body>\n</html>';
fs.writeFile(cov_dir + '/index.html', out, 'utf8', function(err) {
if (err) {
throw err;
}
cb();
});
}
);
};

68
node_modules/tap/lib/tap-global-harness.js generated vendored Normal file
View file

@ -0,0 +1,68 @@
// this is just a harness that pipes to stdout.
// It's the default one.
module.exports = GlobalHarness
var globalHarness = global.TAP_Global_Harness
, inherits = require("inherits")
, Results = require("./tap-results")
, Harness = require("./tap-harness")
, Test = require("./tap-test")
inherits(GlobalHarness, Harness)
function GlobalHarness () {
//console.error("calling GlobalHarness")
if (globalHarness) return globalHarness
if (!(this instanceof GlobalHarness)) {
return globalHarness = new GlobalHarness
}
globalHarness = global.TAP_Global_Harness = this
GlobalHarness.super.call(this, Test)
this.output.pipe(process.stdout)
//this.output.on("data", function () {
// process.nextTick(process.stdout.flush.bind(process.stdout))
//})
this.test = this.test.bind(this)
this.plan = this.plan.bind(this)
var output = this.output
this.on("childEnd", function (child) {
//console.error("childEnd in global harness")
//console.error(child.results)
// write out the stuff for this child.
//console.error("child.conf", child.conf)
output.write(child.conf.name || "(unnamed test)")
// maybe write some other stuff about the number of tests in this
// thing, etc. I dunno.
//console.error("child results", child.results)
this.results.list.forEach(function (res) {
//delete res.error
//console.error("child resuilt", res)
output.write(res)
})
//console.error("wrote child results")
this.results.list.length = 0
})
var streamEnded = false
this.on("end", function () {
//console.error("global ending the stream")
if (!streamEnded) {
this.results.list.forEach(function (res) {
output.write(res)
})
this.results.list.length = 0
output.end()
streamEnded = true
}
})
//this.on("end", this.output.end.bind(this.output))
process.on("unhandledException", function (e) {
this.bailout("unhandled exception: " + e.message)
})
}

219
node_modules/tap/lib/tap-harness.js generated vendored Normal file
View file

@ -0,0 +1,219 @@
// a thing that runs tests.
// Every "test" is also a harness. If they do not have a harness,
// then they are attached to the defaut "global harness",
// which writes its results to stdout.
// TODO:
// - Bailout should stop running any tests.
// - "skip" in the test config obj should skip it.
module.exports = Harness
require("inherits")(Harness, require("events").EventEmitter)
var Results = require("./tap-results")
, TapProducer = require("./tap-producer")
, assert = require("./tap-assert")
function Harness (Test) {
if (!(this instanceof Harness)) return new Harness(Test)
//console.error("Test in "+this.constructor.name, Test)
this._Test = Test
this._plan = null
this._children = []
this._started = false
this._testCount = 0
this._planSum = 0
this.results = new Results()
// emit result events on the harness.
//this.results.on("result", function (res) {
// console.error("proxying result ev from res to harness")
// this.emit("result", res)
//}.bind(this))
var me = this
this.results.on("result", this.emit.bind(this, "result"))
var p = this.process.bind(this)
this.process = function () {
this._started = true
process.nextTick(p)
}
this.output = new TapProducer()
Harness.super.call(this)
}
// this function actually only gets called bound to
// the Harness object, and on process.nextTick. Even if
// passed as an event handler, everything *else* will
// happen before it gets called.
Harness.prototype.process = function () {
//console.error("harness process")
// "end" can emit multiple times, so only actually move on
// to the next test if the current one is actually over.
// TODO: multiple in-process tests, if all are marked "async"
if (this._current) {
if (!this._current._ended) return
// handle the current one before moving onto the next.
this.childEnd(this._current)
}
var skip = true
while (skip) {
//console.error("checking for skips")
var current = this._current = this._children.shift()
if (current) {
skip = current.conf.skip
if (skip) {
//console.error("add a failure for the skipping")
this.results.add(assert.fail(current.conf.name
,{skip:true, diag:false}))
}
} else skip = false
}
// keep processing through skipped tests, instead of running them.
if (current && this._bailedOut) {
return this.process()
}
//console.error("got current?", !!current)
if (current) {
current.on("end", this.process)
current.emit("ready")
//console.error("emitted ready")
//console.error("_plan", this._plan, this.constructor.name)
} else {
//console.error("Harness process: no more left. ending")
if (this._endNice) {
this._endNice()
} else {
this.end()
}
}
}
Harness.prototype.end = function () {
if (this._children.length) {
return this.process()
}
//console.error("harness end", this.constructor.name)
if (this._bailedOut) return
// can't call .end() more than once.
if (this._ended) {
//console.error("adding failure for end calling")
this.results.add(assert.fail("end called more than once"))
}
// see if the plan is completed properly, if there was one.
if (this._plan !== null) {
var total = this._testCount
if (total !== this._plan) {
this.results.add(assert.equal(total, this._plan, "test count != plan"))
}
this._plan = total
}
//console.error("setting ended true", this.constructor.name)
this._ended = true
this.emit("end")
}
Harness.prototype.plan = function (p) {
//console.error("setting plan", new Error().stack)
if (this._plan !== null) {
//console.error("about to add failure for calling plan")
return this.results.add(assert.fail("plan set multiple times"))
}
this._plan = p
if (p === 0 || this.results.testsTotal) {
this.end()
}
}
Harness.prototype.childEnd = function (child) {
//console.error("childEnd")
this._testCount ++
this._planSum += child._plan
//console.error("adding set of child.results")
this.results.addSet(child.results)
this.emit("childEnd", child)
// was this planned?
if (this._plan === this._testCount) {
//console.error("plan", [this._plan, this._testCount])
return this.end()
}
}
function copyObj(o) {
var copied = {}
Object.keys(o).forEach(function (k) { copied[k] = o[k] })
return copied
}
Harness.prototype.test = function test (name, conf, cb) {
if (this._bailedOut) return
if (typeof conf === "function") cb = conf, conf = null
if (typeof name === "object") conf = name, name = null
if (typeof name === "function") cb = name, name = null
conf = (conf ? copyObj(conf) : {})
name = name || ""
//console.error("making test", [name, conf, cb])
// timeout: value in milliseconds. Defaults to 30s
// Set to Infinity to have no timeout.
if (isNaN(conf.timeout)) conf.timeout = 30000
var t = new this._Test(this, name, conf)
var self = this
if (cb) {
//console.error("attaching cb to ready event")
t.on("ready", function () {
if (!isNaN(conf.timeout) && isFinite(conf.timeout)) {
var timer = setTimeout(this.timeout.bind(this), conf.timeout)
var clear = clearTimeout.bind(null, timer)
t.on("end", clear)
t.on("bailout", function (message) {
self.bailout(message)
clear()
})
}
})
t.on("ready", cb.bind(t, t))
// proxy the child results to this object.
//t.on("result", function (res) {
// console.error("in harness, proxying result up")
// t.results.add(res)
//})
}
return t
}
Harness.prototype.bailout = function (message) {
// console.error("Harness bailout", this.constructor.name)
message = message || ""
//console.error("adding bailout message result")
this.results.add({bailout: message})
// console.error(">>> results after bailout" , this.results)
this._bailedOut = true
this.emit("bailout", message)
this.output.end({bailout: message})
}
Harness.prototype.add = function (child) {
//console.error("adding child")
this._children.push(child)
if (!this._started) this.process()
}
// the tearDown function is *always* guaranteed to happen.
// Even if there's a bailout.
Harness.prototype.tearDown = function (fn) {
this.on("end", fn)
}

130
node_modules/tap/lib/tap-producer.js generated vendored Normal file
View file

@ -0,0 +1,130 @@
module.exports = TapProducer
var Results = require("./tap-results")
, inherits = require("inherits")
, yamlish = require("yamlish")
TapProducer.encode = function (result, diag) {
var tp = new TapProducer(diag)
, out = ""
tp.on("data", function (c) { out += c })
if (Array.isArray(result)) {
result.forEach(tp.write, tp)
} else tp.write(result)
tp.end()
return out
}
inherits(TapProducer, require("stream").Stream)
function TapProducer (diag) {
TapProducer.super.call(this)
this.diag = diag
this.count = 0
this.readable = this.writable = true
this.results = new Results
}
TapProducer.prototype.trailer = true
TapProducer.prototype.write = function (res) {
// console.error("TapProducer.write", res)
if (typeof res === "function") throw new Error("wtf?")
if (!this.writable) this.emit("error", new Error("not writable"))
if (!this._didHead) {
this.emit("data", "TAP version 13\n")
this._didHead = true
}
var diag = res.diag
if (diag === undefined) diag = this.diag
this.emit("data", encodeResult(res, this.count + 1, diag))
if (typeof res === "string") return true
if (res.bailout) {
var bo = "bail out!"
if (typeof res.bailout === "string") bo += " " + res.bailout
this.emit("data", bo)
return
}
this.results.add(res, false)
this.count ++
}
TapProducer.prototype.end = function (res) {
if (res) this.write(res)
// console.error("TapProducer end", res, this.results)
this.emit("data", "\n1.."+this.results.testsTotal+"\n")
if (this.trailer && typeof this.trailer !== "string") {
// summary trailer.
var trailer = "tests "+this.results.testsTotal + "\n"
if (this.results.pass) {
trailer += "pass " + this.results.pass + "\n"
}
if (this.results.fail) {
trailer += "fail " + this.results.fail + "\n"
}
if (this.results.skip) {
trailer += "skip "+this.results.skip + "\n"
}
if (this.results.todo) {
trailer += "todo "+this.results.todo + "\n"
}
if (this.results.bailedOut) {
trailer += "bailed out" + "\n"
}
if (this.results.testsTotal === this.results.pass) {
trailer += "\nok\n"
}
this.trailer = trailer
}
if (this.trailer) this.write(this.trailer)
this.writable = false
this.emit("end", null, this.count, this.ok)
}
function encodeResult (res, count, diag) {
// console.error(res, count, diag)
if (typeof res === "string") {
res = res.split(/\r?\n/).map(function (l) {
if (!l.trim()) return l.trim()
return "# " + l
}).join("\n")
if (res.substr(-1) !== "\n") res += "\n"
return res
}
if (res.bailout) return ""
if (!!process.env.TAP_NODIAG) diag = false
else if (!!process.env.TAP_DIAG) diag = true
else if (diag === undefined) diag = !res.ok
var output = ""
res.name = res.name && ("" + res.name).trim()
output += ( !res.ok ? "not " : "") + "ok " + count
+ ( !res.name ? ""
: " " + res.name.replace(/[\r\n]/g, " ") )
+ ( res.skip ? " # SKIP"
: res.todo ? " # TODO"
: "" )
+ "\n"
if (!diag) return output
var d = {}
, dc = 0
Object.keys(res).filter(function (k) {
return k !== "ok" && k !== "name" && k !== "id"
}).forEach(function (k) {
dc ++
d[k] = res[k]
})
//console.error(d, "about to encode")
if (dc > 0) output += " ---"+yamlish.encode(d)+"\n ...\n"
return output
}

71
node_modules/tap/lib/tap-results.js generated vendored Normal file
View file

@ -0,0 +1,71 @@
// A class for counting up results in a test harness.
module.exports = Results
var inherits = require("inherits")
, EventEmitter = require("events").EventEmitter
inherits(Results, EventEmitter)
function Results (r) {
//console.error("result constructor", r)
this.ok = true
this.addSet(r)
}
Results.prototype.addSet = function (r) {
//console.error("add set of results", r)
r = r || {ok: true}
; [ "todo"
, "todoPass"
, "todoFail"
, "skip"
, "skipPass"
, "skipFail"
, "pass"
, "passTotal"
, "fail"
, "failTotal"
, "tests"
, "testsTotal" ].forEach(function (k) {
this[k] = (this[k] || 0) + (r[k] || 0)
//console.error([k, this[k]])
}, this)
this.ok = this.ok && r.ok && true
this.bailedOut = this.bailedOut || r.bailedOut || false
this.list = (this.list || []).concat(r.list || [])
this.emit("set", this.list)
//console.error("after addSet", this)
}
Results.prototype.add = function (r, addToList) {
//console.error("add result", r)
var pf = r.ok ? "pass" : "fail"
, PF = r.ok ? "Pass" : "Fail"
this.testsTotal ++
this[pf + "Total"] ++
if (r.skip) {
this["skip" + PF] ++
this.skip ++
} else if (r.todo) {
this["todo" + PF] ++
this.todo ++
} else {
this.tests ++
this[pf] ++
}
if (r.bailout || typeof r.bailout === "string") {
// console.error("Bailing out in result")
this.bailedOut = true
}
this.ok = !!(this.ok && r.ok)
if (addToList === false) return
this.list = this.list || []
this.list.push(r)
this.emit("result", r)
}

434
node_modules/tap/lib/tap-runner.js generated vendored Normal file
View file

@ -0,0 +1,434 @@
var fs = require("fs")
, child_process = require("child_process")
, path = require("path")
, chain = require("slide").chain
, asyncMap = require("slide").asyncMap
, TapProducer = require("./tap-producer.js")
, TapConsumer = require("./tap-consumer.js")
, assert = require("./tap-assert.js")
, inherits = require("inherits")
, util = require("util")
, CovHtml = require("./tap-cov-html.js")
// XXX Clean up the coverage options
, doCoverage = process.env.TAP_COV
|| process.env.npm_package_config_coverage
|| process.env.npm_config_coverage
module.exports = Runner
inherits(Runner, TapProducer)
function Runner (options, cb) {
this.options = options
var diag = this.options.diag
var dir = this.options.argv.remain
Runner.super.call(this, diag)
this.doCoverage = doCoverage
// An array of full paths to files to obtain coverage
this.coverageFiles = []
// The source of these files
this.coverageFilesSource = {}
// Where to write coverage information
this.coverageOutDir = this.options["coverage-dir"]
// Temporary test files bunkerified we'll remove later
this.f2delete = []
// Raw coverage stats, as read from JSON files
this.rawCovStats = []
// Processed coverage information, per file to cover:
this.covStats = {}
if (dir) {
var filesToCover = this.options.cover
if (doCoverage) {
var mkdirp = require("mkdirp")
this.coverageOutDir = path.resolve(this.coverageOutDir)
this.getFilesToCover(filesToCover)
var self = this
return mkdirp(this.coverageOutDir, 0755, function (er) {
if (er) return self.emit("error", er)
self.run(dir, cb)
})
}
this.run(dir, cb)
}
}
Runner.prototype.run = function() {
var self = this
, args = Array.prototype.slice.call(arguments)
, cb = args.pop() || finish
function finish (er) {
if (er) {
self.emit("error", er)
}
if (!doCoverage) return self.end()
// Cleanup temporary test files with coverage:
self.f2delete.forEach(function(f) {
fs.unlinkSync(f)
})
self.getFilesToCoverSource(function(err, data) {
if (err) {
self.emit("error", err)
}
self.getPerFileCovInfo(function(err, data) {
if (err) {
self.emit("error", err)
}
self.mergeCovStats(function(err, data) {
if (err) {
self.emit("error", err)
}
CovHtml(self.covStats, self.coverageOutDir, function() {
self.end()
})
})
})
})
}
if (Array.isArray(args[0])) {
args = args[0]
}
self.runFiles(args, "", cb)
}
Runner.prototype.runDir = function (dir, cb) {
var self = this
fs.readdir(dir, function (er, files) {
if (er) {
self.write(assert.fail("failed to readdir " + dir, { error: er }))
self.end()
return
}
files = files.sort(function(a, b) {
return a > b ? 1 : -1
})
files = files.filter(function(f) {
return !f.match(/^\./)
})
files = files.map(path.resolve.bind(path, dir))
self.runFiles(files, path.resolve(dir), cb)
})
}
Runner.prototype.runFiles = function (files, dir, cb) {
var self = this
chain(files.map(function(f) {
return function (cb) {
if (self._bailedOut) return
var relDir = dir || path.dirname(f)
, fileName = relDir === "." ? f : f.substr(relDir.length + 1)
self.write(fileName)
fs.lstat(f, function(er, st) {
if (er) {
self.write(assert.fail("failed to stat " + f, {error: er}))
return cb()
}
var cmd = f, args = [], env = {}
if (path.extname(f) === ".js") {
cmd = "node"
args = [fileName]
} else if (path.extname(f) === ".coffee") {
cmd = "coffee"
args = [fileName]
}
if (st.isDirectory()) {
return self.runDir(f, cb)
}
if (doCoverage && path.extname(f) === ".js") {
var foriginal = fs.readFileSync(f, "utf8")
, fcontents = self.coverHeader() + foriginal + self.coverFooter()
, tmpBaseName = path.basename(f, path.extname(f))
+ ".with-coverage." + process.pid + path.extname(f)
, tmpFname = path.resolve(path.dirname(f), tmpBaseName)
, i
fs.writeFileSync(tmpFname, fcontents, "utf8")
args = [tmpFname]
}
for (i in process.env) {
env[i] = process.env[i]
}
env.TAP = 1
var cp = child_process.spawn(cmd, args, { env: env, cwd: relDir })
, out = ""
, err = ""
, tc = new TapConsumer()
, childTests = [f]
var timeout = setTimeout(function () {
if (!cp._ended) {
cp._timedOut = true
cp.kill()
}
}, self.options.timeout * 1000)
tc.on("data", function(c) {
self.emit("result", c)
self.write(c)
})
tc.on("bailout", function (message) {
clearTimeout(timeout)
console.log("# " + f.substr(process.cwd().length + 1))
process.stderr.write(err)
process.stdout.write(out + "\n")
self._bailedOut = true
cp._ended = true
cp.kill()
})
cp.stdout.pipe(tc)
cp.stdout.on("data", function (c) { out += c })
cp.stderr.on("data", function (c) {
if (self.options.stderr) process.stderr.write(c)
err += c
})
cp.on("exit", function (code) {
if (cp._ended) return
cp._ended = true
var ok = !cp._timedOut && !code
clearTimeout(timeout)
//childTests.forEach(function (c) { self.write(c) })
var res = { name: path.dirname(f).replace(process.cwd() + "/", "")
+ "/" + fileName
, ok: ok
, timedOut: cp._timedOut
, exit: code }
if (err) {
res.stderr = err
if (tc.results.ok &&
tc.results.tests === 0 &&
!self.options.stderr) {
// perhaps a compilation error or something else failed.
// no need if stderr is set, since it will have been
// output already anyway.
console.error(err)
}
}
// tc.results.ok = tc.results.ok && ok
tc.results.add(res)
res.command = [cmd].concat(args).map(JSON.stringify).join(" ")
self.emit("result", res)
self.emit("file", f, res, tc.results)
self.write(res)
self.write("\n")
if (doCoverage) {
self.f2delete.push(tmpFname)
}
cb()
})
})
}
}), cb)
return self
}
// Get an array of full paths to files we are interested into obtain
// code coverage.
Runner.prototype.getFilesToCover = function(filesToCover) {
var self = this
filesToCover = filesToCover.split(",").map(function(f) {
return path.resolve(f)
}).filter(function(f) {
return path.existsSync(f)
})
function recursive(f) {
if (path.extname(f) === "") {
// Is a directory:
fs.readdirSync(f).forEach(function(p) {
recursive(f + "/" + p)
})
} else {
self.coverageFiles.push(f)
}
}
filesToCover.forEach(function(f) {
recursive(f)
})
}
// Prepend to every test file to run. Note tap.test at the very top due it
// "plays" with include paths.
Runner.prototype.coverHeader = function() {
// semi here since we're injecting it before the first line,
// and don't want to mess up line numbers in the test files.
return "var ___TAP_COVERAGE = require("
+ JSON.stringify(require.resolve("runforcover"))
+ ").cover(/.*/g);"
}
// Append at the end of every test file to run. Actually, the stuff which gets
// the coverage information.
// Maybe it would be better to move into a separate file template so editing
// could be easier.
Runner.prototype.coverFooter = function() {
var self = this
// This needs to be a string with proper interpolations:
return [ ""
, "var ___TAP = require(" + JSON.stringify(require.resolve("./main.js")) + ")"
, "if (typeof ___TAP._plan === 'number') ___TAP._plan ++"
, "___TAP.test(" + JSON.stringify("___coverage") + ", function(t) {"
, " var covFiles = " + JSON.stringify(self.coverageFiles)
, " , covDir = " + JSON.stringify(self.coverageOutDir)
, " , path = require('path')"
, " , fs = require('fs')"
, " , testFnBase = path.basename(__filename, '.js') + '.json'"
, " , testFn = path.resolve(covDir, testFnBase)"
, ""
, " function asyncForEach(arr, fn, callback) {"
, " if (!arr.length) {"
, " return callback()"
, " }"
, " var completed = 0"
, " arr.forEach(function(i) {"
, " fn(i, function (err) {"
, " if (err) {"
, " callback(err)"
, " callback = function () {}"
, " } else {"
, " completed += 1"
, " if (completed === arr.length) {"
, " callback()"
, " }"
, " }"
, " })"
, " })"
, " }"
, ""
, " ___TAP_COVERAGE(function(coverageData) {"
, " var outObj = {}"
, " asyncForEach(covFiles, function(f, cb) {"
, " if (coverageData[f]) {"
, " var stats = coverageData[f].stats()"
, " , stObj = stats"
, " stObj.lines = stats.lines.map(function (l) {"
, " return { number: l.lineno, source: l.source() }"
, " })"
, " outObj[f] = stObj"
, " }"
, " cb()"
, " }, function(err) {"
, " ___TAP_COVERAGE.release()"
, " fs.writeFileSync(testFn, JSON.stringify(outObj))"
, " t.end()"
, " })"
, " })"
, "})" ].join("\n")
}
Runner.prototype.getFilesToCoverSource = function(cb) {
var self = this
asyncMap(self.coverageFiles, function(f, cb) {
fs.readFile(f, "utf8", function(err, data) {
var lc = 0
if (err) {
cb(err)
}
self.coverageFilesSource[f] = data.split("\n").map(function(l) {
lc += 1
return { number: lc, source: l }
})
cb()
})
}, cb)
}
Runner.prototype.getPerFileCovInfo = function(cb) {
var self = this
, covPath = path.resolve(self.coverageOutDir)
fs.readdir(covPath, function(err, files) {
if (err) {
self.emit("error", err)
}
var covFiles = files.filter(function(f) {
return path.extname(f) === ".json"
})
asyncMap(covFiles, function(f, cb) {
fs.readFile(path.resolve(covPath, f), "utf8", function(err, data) {
if (err) {
cb(err)
}
self.rawCovStats.push(JSON.parse(data))
cb()
})
}, function(f, cb) {
fs.unlink(path.resolve(covPath, f), cb)
}, cb)
})
}
Runner.prototype.mergeCovStats = function(cb) {
var self = this
self.rawCovStats.forEach(function(st) {
Object.keys(st).forEach(function(i) {
// If this is the first time we reach this file, just add the info:
if (!self.covStats[i]) {
self.covStats[i] = {
missing: st[i].lines
}
} else {
// If we already added info for this file before, we need to remove
// from self.covStats any line not duplicated again (since it has
// run on such case)
self.covStats[i].missing = self.covStats[i].missing.filter(
function(l) {
return (st[i].lines.indexOf(l))
})
}
})
})
// This is due to a bug into
// chrisdickinson/node-bunker/blob/feature/add-coverage-interface
// which is using array indexes for line numbers instead of the right number
Object.keys(self.covStats).forEach(function(f) {
self.covStats[f].missing = self.covStats[f].missing.map(function(line) {
return { number: line.number, source: line.source }
})
})
Object.keys(self.coverageFilesSource).forEach(function(f) {
if (!self.covStats[f]) {
self.covStats[f] = { missing: self.coverageFilesSource[f]
, percentage: 0
}
}
self.covStats[f].lines = self.coverageFilesSource[f]
self.covStats[f].loc = self.coverageFilesSource[f].length
if (!self.covStats[f].percentage) {
self.covStats[f].percentage =
1 - (self.covStats[f].missing.length / self.covStats[f].loc)
}
})
cb()
}

109
node_modules/tap/lib/tap-test.js generated vendored Normal file
View file

@ -0,0 +1,109 @@
// This is a very simple test framework that leverages the tap framework
// to run tests and output tap-parseable results.
module.exports = Test
var assert = require("./tap-assert")
, inherits = require("inherits")
, Results = require("./tap-results")
// tests are also test harnesses
inherits(Test, require("./tap-harness"))
function Test (harness, name, conf) {
//console.error("test ctor")
if (!(this instanceof Test)) return new Test(harness, name, conf)
Test.super.call(this, Test)
conf.name = name || conf.name || "(anonymous)"
this.conf = conf
this.harness = harness
this.harness.add(this)
}
// it's taking too long!
Test.prototype.timeout = function () {
// detect false alarms
if (this._ended) return
this.fail("Timeout!")
this.end()
}
Test.prototype.clear = function () {
this._started = false
this._ended = false
this._plan = null
this._bailedOut = false
this._testCount = 0
this.results = new Results()
}
// this gets called if a test throws ever
Test.prototype.threw = function (ex) {
//console.error("threw!", ex.stack)
this.fail(ex.name + ": " + ex.message, { error: ex, thrown: true })
// may emit further failing tests if the plan is not completed
//console.error("end, because it threw")
this.end()
}
Test.prototype.comment = function (m) {
if (typeof m !== "string") {
return this.fail("Test.comment argument must be a string")
}
this.result("\n" + m.trim())
}
Test.prototype.result = function (res) {
this.results.add(res)
this._testCount ++
this.emit("result", res)
if (this._plan === this._testCount) {
process.nextTick(this._endNice.bind(this))
}
}
Test.prototype._endNice = function () {
if (!this._ended) this.end()
}
// parasitic
// Who says you can't do multiple inheritance in js?
Object.getOwnPropertyNames(assert).forEach(function (k) {
if (k === "prototype" || k === "name") return
var d = Object.getOwnPropertyDescriptor(assert, k)
, v = d.value
if (!v) return
d.value = assertParasite(v)
Object.defineProperty(Test.prototype, k, d)
})
function assertParasite (fn) { return function _testAssert () {
//console.error("_testAssert", fn.name, arguments)
if (this._bailedOut) return
var res = fn.apply(assert, arguments)
this.result(res)
return res
}}
// a few tweaks on the EE emit function, because
// we want to catch all thrown errors and bubble up "bailout"
Test.prototype.emit = (function (em) { return function (t) {
// bailouts bubble until handled
if (t === "bailout" &&
this.listeners(t).length === 0 &&
this.harness) {
return this.harness.bailout(arguments[1])
}
if (t === "error") return em.apply(this, arguments)
try {
em.apply(this, arguments)
} catch (ex) {
// any exceptions in a test are a failure
//console.error("caught!", ex.stack)
this.threw(ex)
}
}})(Test.super.prototype.emit)