Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

389
static/js/ketcher2/node_modules/tap/lib/asserts.js generated vendored Normal file
View File

@ -0,0 +1,389 @@
var synonyms = require('./synonyms.js')
var tsame = require('tsame') // same thing, strict or not
var tmatch = require('tmatch') // ok with partial estimates
var extraFromError = require('./extra-from-error.js')
var stack = require('./stack.js')
// Load Buffer the old way for browserify's sake
var Buffer = require('buffer').Buffer // eslint-disable-line
// this is actually the "working half" of the Test class.
// each method figures out if it's a pass or fail, and decorates
// the extra bit, and then calls either pass() or fail() or some
// other assert method.
//
// typically, a plugin would do this on a specific instance, eg on
// the root test harness instance. but we do this here to add some
// useful prototype methods.
exports.decorate = decorate
function decorate (t) {
t.addAssert('ok', 1, function (obj, message, extra) {
message = message || 'expect truthy value'
if (obj) {
return this.pass(message, extra)
}
return this.fail(message, extra)
})
t.addAssert('notOk', 1, function (obj, message, extra) {
message = message || 'expect falsey value'
return this.ok(!obj, message, extra)
})
t.addAssert('error', 1, function (er, message, extra) {
if (!er) {
return this.pass(message || 'should not error', extra)
}
if (!(er instanceof Error)) {
extra.found = er
return this.fail(message || 'non-Error error encountered', extra)
}
message = message || er.message
extra.found = er
return this.fail(message, extra)
})
t.addAssert('equal', 2, function (f, w, m, e) {
m = m || 'should be equal'
if (f === w) {
return this.pass(m, e)
}
e.found = f
e.wanted = w
e.compare = '==='
if (typeof f === 'object' &&
typeof w === 'object' &&
f &&
w &&
tsame(f, w)) {
e.note = 'Objects never === one another'
}
return this.fail(m, e)
})
t.addAssert('not', 2, function (f, w, m, e) {
m = m || 'should not be equal'
if (f !== w) {
return this.pass(m, e)
}
e.found = f
e.doNotWant = w
e.compare = '!=='
return this.fail(m, e)
})
t.addAssert('same', 2, function (f, w, m, e) {
m = m || 'should be equivalent'
e.found = f
e.wanted = w
return this.ok(tsame(f, w), m, e)
})
t.addAssert('notSame', 2, function (f, w, m, e) {
m = m || 'should not be equivalent'
e.found = f
e.doNotWant = w
return this.notOk(tsame(f, w), m, e)
})
t.addAssert('strictSame', 2, function (f, w, m, e) {
m = m || 'should be equivalent strictly'
e.found = f
e.wanted = w
return this.ok(tsame.strict(f, w), m, e)
})
t.addAssert('strictNotSame', 2, function (f, w, m, e) {
m = m || 'should be equivalent strictly'
e.found = f
e.doNotWant = w
return this.notOk(tsame.strict(f, w), m, e)
})
t.addAssert('match', 2, function (f, w, m, e) {
m = m || 'should match pattern provided'
e.found = f
e.pattern = w
return this.ok(tmatch(f, w), m, e)
})
t.addAssert('notMatch', 2, function (f, w, m, e) {
m = m || 'should not match pattern provided'
e.found = f
e.pattern = w
return this.ok(!tmatch(f, w), m, e)
})
t.addAssert('type', 2, function (obj, klass, m, e) {
var name = klass
if (typeof name === 'function') {
name = name.name || '(anonymous constructor)'
}
m = m || 'type is ' + name
// simplest case, it literally is the same thing
if (obj === klass) {
return this.pass(m, e)
}
var type = typeof obj
if (!obj && type === 'object') {
type = 'null'
}
if (type === 'function' &&
typeof klass === 'function' &&
klass !== Object) {
// treat as object, but not Object
// t.type(() => {}, Function)
type = 'object'
}
if (type === 'object' && klass !== 'object') {
if (typeof klass === 'function') {
e.found = Object.getPrototypeOf(obj).constructor.name
e.wanted = name
return this.ok(obj instanceof klass, m, e)
}
// check prototype chain for name
// at this point, we already know klass is not a function
// if the klass specified is an obj in the proto chain, pass
// if the name specified is the name of a ctor in the chain, pass
var p = obj
do {
var ctor = p.constructor && p.constructor.name
if (p === klass || ctor === name) {
return this.pass(m, e)
}
p = Object.getPrototypeOf(p)
} while (p)
}
return this.equal(type, name, m, e)
})
t.addAssert('throws', 4, function (fn_, wanted_, m_, e_, m, e__) {
var fn, wanted, e
for (var i = 0; i < arguments.length - 1; i++) {
var arg = arguments[i]
if (typeof arg === 'function') {
if (arg === Error || arg.prototype instanceof Error) {
wanted = arg
} else if (!fn) {
fn = arg
}
} else if (typeof arg === 'string' && arg) {
m = arg
} else if (typeof arg === 'object') {
if (!wanted) {
wanted = arg
} else {
e = arg
}
}
}
// Copy local properties of the 'extra' object, like 'skip' etc
Object.keys(e__).forEach(function (i) {
e[i] = e__[i]
})
if (!m) {
m = fn && fn.name || 'expected to throw'
}
if (wanted) {
if (wanted instanceof Error) {
var w = {
message: wanted.message
}
if (wanted.name) {
w.name = wanted.name
}
// intentionally copying non-local properties, since this
// is an Error object, and those are funky.
for (i in wanted) {
w[i] = wanted[i]
}
wanted = w
m += ': ' + (wanted.name || 'Error') + ' ' + wanted.message
e = e || {}
if (e !== wanted) {
e.wanted = wanted
}
}
}
if (typeof fn !== 'function') {
e = e || {}
e.todo = true
return this.pass(m, e)
}
try {
fn()
return this.fail(m, e)
} catch (er) {
// 'name' is a getter.
if (er.name) {
er.name = er.name + ''
}
if (wanted) {
if (Object.prototype.toString.call(wanted) === '[object RegExp]') {
return this.match(er.message, wanted, m, e)
}
return this.has(er, wanted, m, e)
} else {
return this.pass(m, e)
}
}
})
t.addAssert('doesNotThrow', 1, function (fn, m, e) {
if (typeof fn === 'string') {
var x = fn
fn = m
m = x
}
if (!m) {
m = fn && fn.name || 'expected to not throw'
}
if (typeof fn !== 'function') {
e.todo = true
return this.pass(m, e)
}
try {
fn()
return this.pass(m, e)
} catch (er) {
var extra = extraFromError(er, e)
extra.message = er.message
return this.fail(m, extra)
}
})
// like throws, but rejects a returned promise instead
// also, can pass in a promise instead of a function
t.addAssert('rejects', 4, function (fn_, wanted_, m_, e_, m, e__) {
var fn, wanted, e, promise
for (var i = 0; i < arguments.length - 1; i++) {
var arg = arguments[i]
if (typeof arg === 'function') {
if (arg === Error || arg.prototype instanceof Error) {
wanted = arg
} else if (!fn) {
fn = arg
}
} else if (typeof arg === 'string' && arg) {
m = arg
} else if (arg && typeof arg.then === 'function' && !promise) {
promise = arg
} else if (typeof arg === 'object') {
if (!wanted) {
wanted = arg
} else {
e = arg
}
}
}
// Copy local properties of the 'extra' object, like 'skip' etc
Object.keys(e__).forEach(function (i) {
e[i] = e__[i]
})
if (!m) {
m = fn && fn.name || 'expect rejected Promise'
}
if (wanted) {
if (wanted instanceof Error) {
var w = {
message: wanted.message
}
if (wanted.name) {
w.name = wanted.name
}
// intentionally copying non-local properties, since this
// is an Error object, and those are funky.
for (i in wanted) {
w[i] = wanted[i]
}
wanted = w
m += ': ' + (wanted.name || 'Error') + ' ' + wanted.message
e = e || {}
if (e !== wanted) {
e.wanted = wanted
}
}
}
if (!promise && typeof fn !== 'function') {
e = e || {}
e.todo = true
return this.pass(m, e)
}
if (!promise)
promise = fn()
if (!promise || typeof promise.then !== 'function')
return this.fail(m, e)
// have to do as a subtest, because promises are async
e.at = stack.at(this.currentAssert)
this.test(m, { buffered: true }, function (t) {
return promise.then(function (value) {
e.found = value
t.fail(m, e)
}, function (er) {
// 'name' is a getter.
if (er.name) {
er.name = er.name + ''
}
if (wanted) {
if (Object.prototype.toString.call(wanted) === '[object RegExp]') {
return t.match(er.message, wanted, m, e)
}
return t.has(er, wanted, m, e)
} else {
return t.pass(m, e)
}
})
})
})
// synonyms are helpful.
Object.keys(synonyms).forEach(function (c) {
if (t[c]) {
synonyms[c].forEach(function (s) {
Object.defineProperty(t, s, {
value: t[c],
enumerable: false,
configurable: true,
writable: true
})
})
}
})
}

254
static/js/ketcher2/node_modules/tap/lib/base.js generated vendored Normal file
View File

@ -0,0 +1,254 @@
module.exports = Base
var Readable = require('stream').Readable
/* istanbul ignore if */
if (!Readable || process.version.match(/^v0\.10/)) {
Readable = require('readable-stream').Readable
}
var extraFromError = require('./extra-from-error.js')
var assert = require('assert')
var cleanYamlObject = require('./clean-yaml-object.js')
var domain = require('domain')
var util = require('util')
util.inherits(Base, Readable)
var Parser = require('tap-parser')
var ownOr = require('own-or')
var ownOrEnv = require('own-or-env')
function Base (options) {
this.start = 0
this.hrtime = null
this.time = null
this.readyToProcess = false
this.options = options
this.grep = ownOr(options, 'grep', [])
this.grepInvert = ownOr(options, 'grepInvert', false)
this.parent = ownOr(options, 'parent', null)
this.bail = ownOrEnv(options, 'bail', 'TAP_BAIL', true)
this.name = ownOr(options, 'name', '')
if (!this.name)
this.name = ''
else
this.name = this.name.replace(/[\n\r\s\t]/g, ' ')
this.indent = ownOr(options, 'indent', '')
this.silent = !!options.silent
this.buffered = !!options.buffered || !!options.silent
this.finished = false
this.strict = ownOrEnv(options, 'strict', 'TAP_STRICT', true)
this.omitVersion = !!options.omitVersion
this.preserveWhitespace = ownOr(options, 'preserveWhitespace', true)
this.jobs = +ownOrEnv(options, 'jobs', 'TAP_JOBS') || 0
this.skip = ownOr(options, 'skip', false)
this.todo = ownOr(options, 'todo', false)
this.runOnly = ownOr(options, 'runOnly', false)
this.setupParser(options)
this.finished = false
this.output = ''
this.results = null
this.bailedOut = false
if (this.skip || this.todo)
this.main = Base.prototype.main
Readable.apply(this, options)
domain.create().add(this)
this.domain.on('error', this.threw.bind(this))
if (typeof options.debug === 'boolean')
this.debug = options.debug ? debug : nodebug
}
Base.prototype.passing = function () {
return this.parser.ok
}
Base.prototype.setTimeout = function (n) {
if (!this.hrtime)
this.hrtime = process.hrtime()
if (!n) {
clearTimeout(this.timer)
this.timer = null
} else {
this.start = Date.now()
this.timer = setTimeout(this.timeout.bind(this), n)
if (this.timer.unref)
this.timer.unref()
}
}
Base.prototype.threw = function (er, extra, proxy) {
if (this.name && !proxy)
er.test = this.name
var message = er.message
if (!extra)
extra = extraFromError(er, extra, this.options)
if (this.results || this.ended) {
this.results.ok = false
if (this.parent)
this.parent.threw(er, extra, true)
else if (!er.stack)
console.error(er)
else {
er.message = message
delete extra.stack
delete extra.at
console.error('%s: %s', er.name || 'Error', message)
console.error(er.stack.split(/\n/).slice(1).join('\n'))
console.error(extra)
}
} else
this.parser.ok = false
return extra
}
Base.prototype.timeout = function (options) {
this.setTimeout(false)
var er = new Error('timeout!')
options = options || {}
options.expired = options.expired || this.name
this.threw(new Error('timeout!'), options)
}
Base.prototype.main = function (cb) {
cb()
}
Base.prototype.online = function (line) {
this.debug('LINE %j', line)
return this.push(this.indent + line)
}
Base.prototype.push = function (c, e) {
assert.equal(typeof c, 'string')
assert.equal(c.substr(-1), '\n')
if (this.buffered) {
this.output += c
return true
}
// We *always* want data coming out immediately. Test runners have a
// very special relationship with zalgo. It's more important to ensure
// that any console.log() lines that appear in the midst of tests are
// not taken out of context
if (this._readableState) {
this._readableState.sync = false
}
// this.debug(this._readableState)
return Readable.prototype.push.call(this, c, e)
}
Base.prototype.onbail = function (reason) {
this.bailedOut = reason || true
this.emit('bailout', reason)
}
Base.prototype.oncomplete = function (results) {
if (this.hrtime) {
this.hrtime = process.hrtime(this.hrtime)
this.time = Math.round(this.hrtime[0] * 1e6 + this.hrtime[1] / 1e3) / 1e3
}
this.debug('ONCOMPLETE %j %j', this.name, results)
if (this.results)
Object.keys(this.results).forEach(function (k) {
results[k] = this.results[k]
}, this)
this.results = results
this.emit('complete', results)
var failures = results.failures.filter(function (f) {
delete f.diag
delete f.ok
return f.tapError
})
if (failures.length)
this.options.failures = failures
this.onbeforeend()
this.emit('end')
this.ondone()
}
Base.prototype.onbeforeend = function () {}
Base.prototype.ondone = function () {}
Base.prototype.setupParser = function (options) {
this.parser = new Parser({
bail: this.bail,
strict: this.strict,
omitVersion: this.omitVersion,
preserveWhitespace: this.preserveWhitespace
})
assert(this.parser.preserveWhitespace)
this.parser.on('line', this.online.bind(this))
this.parser.once('bailout', this.onbail.bind(this))
this.parser.on('complete', this.oncomplete.bind(this))
}
Base.prototype._read = function (n) {
// this.emit('readable')
// this.debug('_read %j', this.name, arguments)
}
Base.prototype.inspect = function () {
return this.constructor.name + ' ' + util.inspect({
name: this.name,
jobs: this.jobs,
buffered: this.buffered,
occupied: this.occupied,
pool: this.pool,
queue: this.queue,
subtests: this.subtests,
output: this.output,
skip: this.skip,
todo: this.todo,
only: this.only,
results: this.results,
options: [
'autoend',
'command',
'args',
'stdio',
'env',
'cwd',
'exitCode',
'signal',
'expired',
'timeout',
'at',
'skip',
'todo',
'only'
].reduce(function (set, k) {
if (this.options[k] !== undefined)
set[k] = this.options[k]
return set
}.bind(this), {})
})
}
Base.prototype.debug = (/\btap\b/i.test(process.env.NODE_DEBUG || ''))
? debug : nodebug
function nodebug () {}
/* istanbul ignore next */
function debug () {
var prefix = 'TAP ' + process.pid + ' ' + this.name + ': '
var msg = util.format.apply(util, arguments).trim()
msg = prefix + msg.split('\n').join('\n' + prefix)
console.error(msg)
}

View File

@ -0,0 +1,72 @@
var cleanYamlObject = require('clean-yaml-object')
var path = require('path')
var Module = require('module')
var fs = require('fs')
var binpath = path.resolve(__dirname, '../bin')
var stack = require('./stack.js')
var Domain = require('domain').Domain
function hasOwn (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key)
}
module.exports = cleanTapYamlObject
function cleanTapYamlObject (object) {
if (hasOwn(object, 'stack') && !hasOwn(object, 'at'))
object.at = stack.parseLine(object.stack.split('\n')[0])
var file = object.at && object.at.file && path.resolve(object.at.file)
if (file && (file.indexOf(__dirname) === 0 || file.indexOf(binpath) === 0))
delete object.at
if (object.at && object.at.file && object.at.line && !object.source) {
var content
file = path.resolve(object.at.file)
try {
content = Module.wrap(fs.readFileSync(file))
} catch (er) {}
if (content) {
content = (content.split('\n')[object.at.line - 1] || '').trim()
if (content)
object.source = content + '\n'
}
}
return cleanYamlObject(object, yamlFilter)
}
function yamlFilter (propertyName, isRoot, source, target) {
if (source instanceof Domain)
return false
if (!isRoot)
return true
if (propertyName === 'stack') {
if (source.stack)
target.stack = source.stack
return false
}
return !(propertyName === 'todo' ||
propertyName === 'time' ||
/^_?tapChild/.test(propertyName) ||
/^tapStream/.test(propertyName) ||
/^tapMochaTest/.test(propertyName) ||
propertyName === 'cb' ||
propertyName === 'name' ||
propertyName === 'indent' ||
propertyName === 'skip' ||
propertyName === 'bail' ||
propertyName === 'grep' ||
propertyName === 'grepInvert' ||
propertyName === 'only' ||
propertyName === 'diagnostic' ||
propertyName === 'buffered' ||
propertyName === 'parent' ||
propertyName === 'domainEmitter' ||
propertyName === 'domainThrew' ||
propertyName === 'domain' ||
(propertyName === 'at' && !source.at))
}

11
static/js/ketcher2/node_modules/tap/lib/diags.js generated vendored Normal file
View File

@ -0,0 +1,11 @@
module.exports = diags
var objToYaml = require('./obj-to-yaml.js')
function diags (extra) {
var y = objToYaml(extra)
if (y)
y = '\n' + y
return y
}

View File

@ -0,0 +1,47 @@
var stack = require('./stack.js')
module.exports = function (er, extra, options) {
extra = Object.keys(options || {}).reduce(function (set, k) {
if (!(k in set) && !/^tapChild/.test(k))
set[k] = options[k]
return set
}, extra || {})
if (!er || typeof er !== 'object') {
extra.error = er
return extra
}
var message = er.message
var addName = true
if (!message && er.stack) {
message = er.stack.split('\n')[0]
addName = false
}
er.message = ''
var st = er.stack
if (st) {
st = st.split('\n')
// parse out the 'at' bit from the first line.
extra.at = stack.parseLine(st[1])
extra.stack = stack.clean(st)
}
er.message = message
if (er.name && er.name !== 'Error')
extra.type = er.name
Object.keys(er).forEach(function (k) {
if (k === 'message' ||
k === 'domainEmitter' ||
k === 'domainThrown' ||
k === 'domain' ||
k === 'domainBound')
return
extra[k] = er[k]
})
return extra
}

147
static/js/ketcher2/node_modules/tap/lib/mocha.js generated vendored Normal file
View File

@ -0,0 +1,147 @@
exports.it = exports.specify = it
exports.context = exports.describe = describe
exports.before = before
exports.after = after
exports.beforeEach = beforeEach
exports.afterEach = afterEach
exports.global = function () {
Object.keys(exports).forEach(function (g) {
global[g] = exports[g]
})
}
var t = require('./tap.js')
t.jobs = 1
var tapStack = [ t ]
var level = 0
var suiteStack = []
function describe (name, fn) {
new Suite(name, fn)
}
function Suite (name, fn) {
this.parent = suiteStack[ suiteStack.length - 1 ]
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
this.todo = !fn
this.fn = fn
this.name = name
this.after = []
this.test = null
this.run()
}
Suite.prototype.run = function () {
var t = tapStack[ tapStack.length - 1 ]
t.test(this.name, { todo: this.todo }, function (tt) {
this.test = tt
tapStack.push(tt)
suiteStack.push(this)
var ret = this.fn()
this.runAfter()
suiteStack.pop()
return ret
}.bind(this))
}
Suite.prototype.runAfter = function () {
this.after.forEach(function (namefn) {
var name = namefn[0]
var fn = namefn[1]
before(name, fn)
})
do {
var t = tapStack.pop()
} while (t && t !== this.test)
if (this.test && !this.test.results)
t.end()
}
function before (name, fn) {
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
var todo = !fn
var suite = suiteStack[ suiteStack.length - 1 ]
var t = tapStack[ tapStack.length - 1 ]
if (!name)
name = ''
t.test(name, { todo: todo, silent: true }, function (tt) {
var ret = fn.call(suite, done(tt))
if (!ret && fn.length === 0)
tt.end()
else
return ret
})
function done (tt) { return function (er) {
if (er)
tt.threw(er)
else
tt.end()
}}
}
function it (name, fn) {
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
var todo = !fn
var suite = suiteStack[ suiteStack.length - 1 ]
var t = tapStack[ tapStack.length - 1 ]
if (!name)
name = ''
t.test(name, { todo: todo, tapMochaTest: true }, function (tt) {
var ret = fn.call(tt, done(tt))
if (ret && ret.then)
return ret
else if (fn.length === 0)
tt.end()
})
function done (tt) { return function (er) {
if (er)
tt.threw(er)
else
tt.end()
}}
}
function after (name, fn) {
var suite = suiteStack[ suiteStack.length - 1 ]
if (!suite)
throw new Error('cannot call "after" outside of describe()')
if (fn)
suite.after.push([name, fn])
else
suite.after.push([name])
}
function moment (when, fn) {
var t = tapStack[ tapStack.length - 1 ]
t[when](function (cb) {
if (!this.options.tapMochaTest)
return cb()
var suite = suiteStack[ suiteStack.length - 1 ]
var ret = fn.call(this, cb)
if (ret && ret.then)
return ret
else if (fn.length === 0)
return cb()
})
}
function beforeEach (fn) {
moment('beforeEach', fn)
}
function afterEach (fn) {
moment('afterEach', fn)
}

17
static/js/ketcher2/node_modules/tap/lib/obj-to-yaml.js generated vendored Normal file
View File

@ -0,0 +1,17 @@
module.exports = objToYaml
var cleanYamlObject = require('./clean-yaml-object.js')
var yaml = require('js-yaml')
function objToYaml (obj) {
obj = cleanYamlObject(obj)
var y = ''
if (obj && typeof obj === 'object' && Object.keys(obj).length) {
y = yaml.safeDump(obj).split('\n').map(function (l) {
return l.trim() ? ' ' + l : l.trim()
}).join('\n')
y = ' ---\n' + y + ' ...\n'
}
return y
}

View File

@ -0,0 +1,64 @@
function typeOf (arg) {
var t = typeof arg
switch (t) {
case 'object':
return arg ? 'object' : 'null'
default:
return t
}
}
module.exports = function (name_, extra_, cb_, defaultName) {
var name
var extra
var cb
// this only works if it's literally the 4th argument. it's mostly
// used internally.
defaultName = defaultName || '(unnamed test)'
for (var i = 0; i < 3 && i < arguments.length; i++) {
var arg = arguments[i]
var type = typeOf(arg)
if (name === undefined && (type === 'string' || type === 'number'))
name = '' + arg
else if (type === 'object') {
extra = arg
if (name === undefined)
name = null
} else if (type === 'function') {
if (extra === undefined)
extra = {}
if (name === undefined)
name = null
cb = arg
} else if (arg === false) {
// it's handy while developing to put a ! in front of a
// function to temporarily make a test TODO
continue
} else if (type !== 'undefined')
throw new TypeError('unknown argument passed to parseTestArgs: ' + type)
}
if (!extra)
extra = {}
if (!cb)
extra.todo = true
if (!name && extra.name)
name = extra.name
if (!name && cb && cb.name)
name = cb.name
name = name || defaultName
extra.name = name
extra.cb = cb || todoCb
return extra
}
/* istanbul ignore next */
function todoCb () {
throw new Error('callback called for TODO test')
}

48
static/js/ketcher2/node_modules/tap/lib/point.js generated vendored Normal file
View File

@ -0,0 +1,48 @@
module.exports = TestPoint
var path = require('path')
var binpath = path.resolve(__dirname, '../bin')
var util = require('util')
var diags = require('./diags.js')
function TestPoint (ok, message, extra) {
if (typeof ok !== 'boolean')
throw new TypeError('ok must be boolean')
if (!(this instanceof TestPoint))
return new TestPoint(ok, message, extra)
this.ok = ok ? 'ok ' : 'not ok '
this.message = tpMessage(message, extra)
}
function tpMessage (message, extra) {
message = message + ''
if (message)
message = ' - ' + message
message = message.replace(/[\n\r]/g, ' ').replace(/\t/g, ' ')
extra = extra || {}
if (extra.skip) {
message += ' # SKIP'
if (typeof extra.skip === 'string')
message += ' ' + extra.skip
} else if (extra.todo) {
message += ' # TODO'
if (typeof extra.todo === 'string')
message += ' ' + extra.todo
} else if (extra.time)
message += ' # time=' + extra.time + 'ms'
var diagYaml = extra.diagnostic ? diags(extra) : ''
message += diagYaml
if (extra.tapChildBuffer || extra.tapChildBuffer === '') {
if (!diagYaml)
message += ' '
message += '{\n' + extra.tapChildBuffer.trimRight() + '\n}\n'
}
message += '\n'
return message
}

140
static/js/ketcher2/node_modules/tap/lib/spawn.js generated vendored Normal file
View File

@ -0,0 +1,140 @@
var Base = require('./base.js')
var assert = require('assert')
var util = require('util')
util.inherits(Spawn, Base)
var ownOr = require('own-or')
var path = require('path')
var cleanYamlObject = require('./clean-yaml-object.js')
module.exports = Spawn
var cp = require('child_process')
var spawn = cp.spawn
function Spawn (options) {
options = options || {}
if (!(this instanceof Spawn))
return new Spawn(options)
Base.call(this, options)
this.command = options.command
if (!this.command)
throw new TypeError('no command provided')
this.args = options.args
// stdout must be a pipe
if (options.stdio) {
if (typeof options.stdio === 'string')
this.stdio = [ options.stdio, 'pipe', options.stdio ]
else
this.stdio = options.stdio.slice(0)
} else
this.stdio = [ 0, 'pipe', 2 ]
this.stdio[1] = 'pipe'
var env = options.env || process.env
this.env = Object.keys(env).reduce(function (e, k) {
e[k] = env[k]
return e
}, {})
this.env.TAP = '1'
if (this.bail)
this.env.TAP_BAIL = '1'
this.cwd = ownOr(options, 'cwd', process.cwd())
options.cwd = this.cwd
if (!this.name) {
if (this.command === process.execPath) {
this.name = path.basename(process.execPath) + ' ' +
this.args.map(function (a) {
if (a.indexOf(this.cwd) === 0) {
return './' +
a.substr(this.cwd.length + 1).replace(/\\/g, '/')
} else {
return a
}
}, this).join(' ')
} else {
this.name = this.command + ' ' + this.args.join(' ')
}
}
this.proc = null
}
Spawn.prototype.endAll = function () {
if (this.proc)
this.proc.kill('SIGKILL')
this.parser.abort('test unfinished')
this.cb()
}
Spawn.prototype.main = function (cb) {
this.cb = cb
this.setTimeout(this.options.timeout)
var options = Object.keys(this.options).reduce(function (o, k) {
o[k] = this.options[k]
return o
}.bind(this), {
cwd: this.cwd,
env: this.env,
stdio: this.stdio
})
try {
var proc = this.proc = spawn(this.command, this.args, options)
proc.stdout.pipe(this.parser)
proc.on('close', this.onprocclose.bind(this))
proc.on('error', this.threw.bind(this))
} catch (er) {
this.threw(er)
}
}
Spawn.prototype.threw = function (er, extra, proxy) {
extra = Base.prototype.threw.call(this, er, extra, proxy)
extra = cleanYamlObject(extra)
// unhook entirely
this.parser.abort(er.message, extra)
if (this.proc) {
this.proc.stdout.removeAllListeners('data')
this.proc.stdout.removeAllListeners('end')
this.proc.removeAllListeners('close')
this.proc.kill('SIGKILL')
}
this.cb()
}
Spawn.prototype.onprocclose = function (code, signal) {
this.debug('SPAWN close %j %s', code, signal)
this.options.exitCode = code
if (signal)
this.options.signal = signal
this.results = this.results || {}
// spawn closing with no tests is treated as a skip.
if (this.results.plan && this.results.plan.skipAll && !code && !signal)
this.options.skip = this.results.plan.skipReason || true
if (code || signal) {
this.results.ok = false
this.parser.ok = false
}
return this.cb()
}
Spawn.prototype.timeout = function (extra) {
if (this.proc)
this.proc.kill('SIGTERM')
var t = setTimeout(function () {
if (!this.options.signal && this.options.exitCode === undefined) {
Base.prototype.timeout.call(this, extra)
this.proc.kill('SIGKILL')
}
}.bind(this), 1000)
if (t.unref)
t.unref()
}

28
static/js/ketcher2/node_modules/tap/lib/stack.js generated vendored Normal file
View File

@ -0,0 +1,28 @@
var sourceMapSupport = require('source-map-support')
var StackUtils = require('stack-utils')
var path = require('path')
var tapDir = path.resolve(__dirname, '..')
// don't skip when developing on tap itself
var skip = process.cwd() !== tapDir ||
+process.env.TAP_DEV_SHORTSTACK === 1 &&
+process.env.TAP_DEV_LONGSTACK !== 1
? [
/node_modules[\/\\]tap[\/\\]/,
new RegExp(resc(tapDir) + '\\b', 'i'),
new RegExp(resc(require.resolve('function-loop'))),
new RegExp(resc(path.dirname(require.resolve('bluebird/package.json'))))
]
: []
sourceMapSupport.install({environment:'node'})
// Ignore tap if it's a dependency, or anything
// in this lib folder.
module.exports = new StackUtils({
internals: StackUtils.nodeInternals().concat(skip),
wrapCallSite: sourceMapSupport.wrapCallSite
})
function resc(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

36
static/js/ketcher2/node_modules/tap/lib/stdin.js generated vendored Normal file
View File

@ -0,0 +1,36 @@
var Base = require('./base.js')
var util = require('util')
var ownOr = require('own-or')
var domain = require('domain')
util.inherits(Stdin, Base)
module.exports = Stdin
function Stdin (options) {
options = options || {}
if (!(this instanceof Stdin))
return new Stdin(options)
options.name = ownOr(options, 'name', '/dev/stdin')
Base.call(this, options)
// This has to be here for node 0.10's wonky streams
this.stream = ownOr(options, 'tapStream', process.stdin)
this.stream.pause()
}
Stdin.prototype.main = function (cb) {
this.domain.add(this.stream)
this.setTimeout(this.options.timeout)
this.stream.pipe(this.parser)
this.stream.resume()
this.once('end', cb)
}
Stdin.prototype.threw = function (er, extra, proxy) {
extra = Base.prototype.threw.call(this, er, extra, proxy)
this.options = extra
this.parser.abort(er.message, extra)
this.parser.end()
}

88
static/js/ketcher2/node_modules/tap/lib/synonyms.js generated vendored Normal file
View File

@ -0,0 +1,88 @@
// A list of all the synonyms of assert methods.
// In addition to these, multi-word camelCase are also synonymized to
// all lowercase and snake_case
module.exports = multiword({
ok: ['true', 'assert'],
notOk: ['false', 'assertNot'],
error: ['ifError', 'ifErr'],
throws: ['throw'],
doesNotThrow: ['notThrow'],
// exactly the same. ===
equal: [
'equals', 'isEqual', 'is', 'strictEqual', 'strictEquals', 'strictIs',
'isStrict', 'isStrictly'
],
// not equal. !==
not: [
'inequal', 'notEqual', 'notEquals', 'notStrictEqual', 'notStrictEquals',
'isNotEqual', 'isNot', 'doesNotEqual', 'isInequal'
],
// deep equivalence. == for scalars
same: [
'equivalent', 'looseEqual', 'looseEquals', 'deepEqual',
'deepEquals', 'isLoose', 'looseIs', 'isEquivalent'
],
// deep inequivalence. != for scalars
notSame: [
'inequivalent', 'looseInequal', 'notDeep', 'deepInequal',
'notLoose', 'looseNot', 'notEquivalent', 'isNotDeepEqual',
'isNotDeeply', 'notDeepEqual', 'isInequivalent',
'isNotEquivalent'
],
// deep equivalence, === for scalars
strictSame: [
'strictEquivalent', 'strictDeepEqual', 'sameStrict', 'deepIs',
'isDeeply', 'isDeep', 'strictDeepEquals'
],
// deep inequivalence, !== for scalars
strictNotSame: [
'strictInequivalent', 'strictDeepInequal', 'notSameStrict', 'deepNot',
'notDeeply', 'strictDeepInequals', 'notStrictSame'
],
// found has the fields in wanted, string matches regexp
match: [
'has', 'hasFields', 'matches', 'similar', 'like', 'isLike',
'includes', 'include', 'isSimilar', 'contains'
],
notMatch: [
'dissimilar', 'unsimilar', 'notSimilar', 'unlike', 'isUnlike',
'notLike', 'isNotLike', 'doesNotHave', 'isNotSimilar', 'isDissimilar'
],
type: [
'isa', 'isA'
]
})
function multiword (obj) {
Object.keys(obj).forEach(function (i) {
var list = obj[i]
var res = [ multiword_(i) ].concat(list.map(multiword_))
res = res.reduce(function (set, i) {
set.push.apply(set, i)
return set
}, [])
obj[i] = res
})
return obj
}
function multiword_ (str) {
var res = [ str ]
if (str.match(/[A-Z]/)) {
res.push(str.toLowerCase())
res.push(str.replace(/[A-Z]/g, function ($0) {
return '_' + $0.toLowerCase()
}))
}
return res
}

216
static/js/ketcher2/node_modules/tap/lib/tap.js generated vendored Normal file
View File

@ -0,0 +1,216 @@
var Test = require('./test.js')
var Stdin = require('./stdin.js')
var Spawn = require('./spawn.js')
var util = require('util')
var objToYaml = require('./obj-to-yaml.js')
var yaml = require('js-yaml')
util.inherits(TAP, Test)
function TAP (options) {
Test.call(this, options)
this.runOnly = process.env.TAP_ONLY === '1'
this.start = Date.now()
}
var didPipe = false
TAP.prototype.pipe = function () {
didPipe = true
this.setTimeout(this.options.timeout)
this.pipe = Test.prototype.pipe
this.push = Test.prototype.push
var ret = this.pipe.apply(this, arguments)
this.process()
return ret
}
function monkeypatchEpipe () {
process.stdout.emit = function (emit) {
return function (ev, er) {
if (ev === 'error' && er.code === 'EPIPE')
return this.emit = emit
return emit.apply(this, arguments)
}
}(process.stdout.emit)
}
function monkeypatchExit () {
// ensure that we always get run, even if a user does
// process.on('exit', process.exit)
process.reallyExit = function (original) {
return function reallyExit (code) {
code = onExitEvent(code)
return original.call(this, code)
}
}(process.reallyExit)
process.exit = function (original) {
return function exit (code) {
code = onExitEvent(code)
return original.call(this, code)
}
}(process.exit)
process.on('exit', onExitEvent)
}
var didOnExitEvent = false
function onExitEvent (code) {
if (didOnExitEvent)
return process.exitCode || code
didOnExitEvent = true
if (!tap.results)
tap.endAll()
if (tap.results && !tap.results.ok && code === 0) {
process.exitCode = 1
if (process.version.match(/^v0\.(10|[0-9])\./))
process.exit(code)
}
return process.exitCode || code || 0
}
TAP.prototype.push = function push () {
// this resets push and pipe to standard values
this.pipe(process.stdout)
this.patchProcess()
return this.push.apply(this, arguments)
}
TAP.prototype.patchProcess = function () {
monkeypatchEpipe()
monkeypatchExit()
process.on('uncaughtException', this.threw)
process.on('unhandledRejection', function (er) {
this.threw(er)
}.bind(this))
}
TAP.prototype.onbail = function () {
Test.prototype.onbail.apply(this, arguments)
this.endAll()
process.exit(1)
}
TAP.prototype.onbeforeend = function () {
if (didPipe && this.time && !this.bailedOut)
this.emit('data', '# time=' + this.time + 'ms\n')
}
TAP.prototype.ondone = function () {
try {
this.emit('teardown')
} catch (er) {
this.threw(er)
}
}
// Root test runner doesn't have the 'teardown' event, because it
// isn't hooked into any parent Test as a harness.
TAP.prototype.teardown = TAP.prototype.tearDown = function (fn) {
this.autoend()
return Test.prototype.teardown.apply(this, arguments)
}
var opt = { name: 'TAP' }
if (process.env.TAP_DEBUG === '1' ||
/\btap\b/.test(process.env.NODE_DEBUG || ''))
opt.debug = true
if (process.env.TAP_GREP) {
opt.grep = process.env.TAP_GREP.split('\n').map(function (g) {
var p = g.match(/^\/(.*)\/([a-z]*)$/)
g = p ? p[1] : g
var flags = p ? p[2] : ''
return new RegExp(g, flags)
})
}
if (process.env.TAP_GREP_INVERT === '1') {
opt.grepInvert = true
}
if (process.env.TAP_ONLY === '1') {
opt.only = true
}
var tap = new TAP(opt)
module.exports = tap
tap.mocha = require('./mocha.js')
tap.mochaGlobals = tap.mocha.global
tap.Test = Test
tap.Spawn = Spawn
tap.Stdin = Stdin
tap.synonyms = require('./synonyms.js')
// SIGTERM means being forcibly killed, almost always by timeout
var onExit = require('signal-exit')
var didTimeoutKill = false
onExit(function (code, signal) {
if (signal !== 'SIGTERM' || !didPipe || didTimeoutKill)
return
var handles = process._getActiveHandles().filter(function (h) {
return h !== process.stdout &&
h !== process.stdin &&
h !== process.stderr
})
var requests = process._getActiveRequests()
// Ignore this because it's really hard to test cover in a way
// that isn't inconsistent and unpredictable.
/* istanbul ignore next */
var extra = {
at: null,
signal: signal
}
if (requests.length) {
extra.requests = requests.map(function (r) {
var ret = { type: r.constructor.name }
if (r.context) {
ret.context = r.context
}
return ret
})
}
if (handles.length) {
extra.handles = handles.map(function (h) {
var ret = { type: h.constructor.name }
if (h.msecs) {
ret.msecs = h.msecs
}
if (h._events) {
ret.events = Object.keys(h._events)
}
if (h._sockname) {
ret.sockname = h._sockname
}
if (h._connectionKey) {
ret.connectionKey = h._connectionKey
}
return ret
})
}
// this is impossible to cover, because it happens after nyc has
// already done its stuff.
/* istanbul ignore else */
if (!tap.results && tap.timeout)
tap.timeout(extra)
else {
console.error('possible timeout: SIGTERM received after tap end')
if (extra.handles || extra.requests) {
delete extra.signal
if (!extra.at) {
delete extra.at
}
var yaml = require('js-yaml')
console.error(objToYaml(extra))
}
didTimeoutKill = true
process.kill(process.pid, 'SIGTERM')
}
})

789
static/js/ketcher2/node_modules/tap/lib/test.js generated vendored Normal file
View File

@ -0,0 +1,789 @@
// We need TWO queues (work and subtest) and one jobs pool
//
// The pool stores buffered subtests being run in parallel.
//
// When new subtests are created, they get put in the work queue and also
// in the subtests queue if they are buffered and jobs>0. When we put a
// test in the subtest queue, we also process it.
//
// Processing the subtest queue means moving tests into the jobs pool until
// the jobs pool length is at this.jobs
//
// Any output functions get put in the work queue if its length > 0 (ie,
// no cutting the line)
//
// Processing the work queue means walking until we run out of things, or
// encounter an unfinished test. When we encounter ANY kind of test, we
// block until its output is completed, dumping it all into the parser.
var Base = require('./base.js')
var Spawn = require('./spawn.js')
var Stdin = require('./stdin.js')
var Deferred = require('trivial-deferred')
var Pool = require('yapool')
var TestPoint = require('./point.js')
var parseTestArgs = require('./parse-test-args.js')
var loop = require('function-loop')
var extraFromError = require('./extra-from-error.js')
var stack = require('./stack.js')
var assert = require('assert')
var util = require('util')
util.inherits(Test, Base)
var ownOr = require('own-or')
var ownOrEnv = require('own-or-env')
var tapAsserts = require('./asserts.js')
var Promise = require('bluebird')
var bindObj = require('bind-obj-methods')
// A sigil object for implicit end() calls that should not
// trigger an error if the user then calls t.end()
var IMPLICIT = {}
// Sigil to put in the queue to signal the end of all things
var EOF = { EOF: true }
function hasOwn (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key)
}
module.exports = Test
function Test (options) {
options = options || {}
if (!(this instanceof Test))
return new Test(options)
Base.call(this, options)
this.pushedEnd = false
this.jobs = ownOr(options, 'jobs', 1)
this.subtests = []
this.pool = new Pool()
this.queue = ['TAP version 13\n']
this.noparallel = false
this.cb = this.domain.bind(options.cb)
this.occupied = false
this.currentAssert = null
this.count = 0
this.n = 0
this.ended = false
this.explicitEnded = false
this.multiEndThrew = false
this.currentAssert = null
this.assertAt = null
this.assertStack = null
this.planEnd = -1
this.onBeforeEach = []
this.onAfterEach = []
this.ranAfterEach = false
// bind all methods to this object, so we can pass t.end as a callback
// and do `var test = require('tap').test` like people do.
var bound = Object.create(null)
bindObj(this, this, bound)
bindObj(this, Object.getPrototypeOf(this), bound)
bindObj(this, Test.prototype, bound)
}
Test.prototype.current = function () {
throw new Error('Test.current() as been removed and is no more')
}
Test.prototype.spawn = function spawn (cmd, args, options, name) {
if (typeof args === 'string') {
args = [ args ]
}
args = args || []
if (typeof options === 'string') {
name = options
options = {}
}
options = options || {}
options.name = ownOr(options, 'name', name)
options.command = cmd
options.args = args
return this.sub(Spawn, options, spawn)
}
Test.prototype.sub = function (Class, extra, caller) {
extra = extra || {}
if (!extra.skip && this.grep.length) {
var match = this.grep[0].test(extra.name)
if (this.grepInvert) {
match = !match
}
if (!match) {
var p = 'filter' + (this.grepInvert ? ' out' : '') + ': '
extra.skip = p + this.grep[0]
}
}
if (extra.only && !this.runOnly) {
this.comment('%j has `only` set but all tests run', extra.name)
}
if (this.runOnly && !extra.only) {
extra.skip = 'filter: only'
}
if (extra.todo || extra.skip) {
this.pass(extra.name, extra)
return Promise.resolve(this)
}
if (!extra.grep) {
extra.grep = this.grep.slice(1)
extra.grepInvert = this.grepInvert
}
extra.indent = ' '
if (this.jobs > 1 && process.env.TAP_BUFFER === undefined)
extra.buffered = ownOr(extra, 'buffered', true)
else
extra.buffered = ownOrEnv(extra, 'buffered', 'TAP_BUFFER', true)
extra.bail = ownOr(extra, 'bail', this.bail)
extra.parent = this
extra.stack = stack.captureString(80, caller)
var t = new Class(extra)
this.queue.push(t)
this.subtests.push(t)
var d = new Deferred()
t.deferred = d
this.process()
return d.promise
}
Test.prototype.only = function test (name, extra, cb) {
extra = parseTestArgs(name, extra, cb)
extra.only = true
return this.sub(Test, extra, test)
}
Test.prototype.test = function test (name, extra, cb) {
extra = parseTestArgs(name, extra, cb)
return this.sub(Test, extra, test)
}
Test.prototype.stdin = function stdin (name, extra) {
extra = parseTestArgs(name, extra, function () {}, '/dev/stdin')
return this.sub(Stdin, extra || {}, stdin)
}
Test.prototype.bailout = function (message) {
if (this.parent && (this.results || this.ended))
this.parent.bailout(message)
else {
this.process()
message = message ? ' ' + ('' + message).trim() : ''
message = message.replace(/[\r\n]/g, ' ')
this.parser.write('Bail out!' + message + '\n')
}
this.end(IMPLICIT)
this.process()
}
Test.prototype.comment = function () {
var message = util.format.apply(util, arguments)
message = '# ' + message.split(/\r?\n/).join('\n# ') + '\n'
if (this.results)
this.push(message)
else
this.queue.push(message)
this.process()
}
Test.prototype.timeout = function (options) {
options = options || {}
options.expired = options.expired || this.name
if (this.occupied)
this.occupied.timeout(options)
else
Base.prototype.timeout.call(this, options)
this.end(IMPLICIT)
}
Test.prototype.main = function (cb) {
this.setTimeout(this.options.timeout)
this.debug('MAIN pre', this)
var self = this
try {
var ret = this.cb(this)
} catch (er) {
this.threw(er)
}
if (ret && ret.then) {
this.promise = ret
ret.tapAbortPromise = done
ret.then(end, done)
} else
done()
function end () {
self.debug(' > implicit end for promise')
self.end(IMPLICIT)
done()
}
function done (er) {
if (er)
self.threw(er)
if (self.results || self.bailedOut)
cb()
else
self.ondone = cb
}
this.debug('MAIN post', this)
}
Test.prototype.process = function () {
if (this.processing)
return this.debug(' < already processing')
this.debug('\nPROCESSING(%s)', this.name, this.queue.length)
this.processing = true
var p
while (!this.occupied && (p = this.queue.shift())) {
this.debug('PROCESS(%s)', this.name, p)
if (p instanceof Base) {
this.processSubtest(p)
} else if (p === EOF) {
this.debug(' > EOF', this.name)
// I AM BECOME EOF, DESTROYER OF STREAMS
this.parser.end()
} else if (p instanceof TestPoint) {
this.debug(' > TESTPOINT')
this.parser.write(p.ok + (++this.n) + p.message)
} else if (typeof p === 'string') {
this.debug(' > STRING')
this.parser.write(p)
} else if (Array.isArray(p)) {
this.debug(' > METHOD')
var m = p.shift()
this[m].apply(this, p)
} else {
throw new Error('weird thing got in the queue')
}
}
while (!this.noparallel &&
this.pool.length < this.jobs &&
(p = this.subtests.shift())) {
if (!p.buffered) {
this.noparallel = true
break
}
this.debug('start subtest', p)
this.pool.add(p)
if (this.bailedOut)
this.onbufferedend(p)
else
this.runBeforeEach(p,
p.main.bind(p,
this.onbufferedend.bind(this, p)))
}
this.debug('done processing', this.queue, this.occupied)
this.processing = false
// just in case any tests ended, and we have sync stuff still
// waiting around in the queue to be processed
if (!this.occupied && this.queue.length)
this.process()
this.maybeAutoend()
}
Test.prototype.processSubtest = function (p) {
this.debug(' > subtest')
this.occupied = p
if (!p.buffered) {
if (this.bailedOut)
return this.onindentedend(p)
this.debug(' > subtest indented')
p.pipe(this.parser, { end: false })
this.runBeforeEach(p,
this.writeSubComment.bind(this, p,
p.main.bind(p,
this.onindentedend.bind(this, p))))
} else if (p.readyToProcess) {
this.debug(' > subtest buffered, finished')
// finished! do the thing!
this.occupied = null
if (!p.passing() || !p.silent) {
this.queue.unshift(['emitSubTeardown', p])
this.printResult(p.passing(), p.name, p.options, true)
}
} else {
this.occupied = p
this.debug(' > subtest buffered, unfinished', p)
// unfinished buffered test.
// nothing to do yet, just leave it there.
this.queue.unshift(p)
}
}
Test.prototype.emitSubTeardown = function (p) {
try {
p.emit('teardown')
} catch (er) {
delete p.options.time
p.threw(er)
}
}
Test.prototype.writeSubComment = function (p, cb) {
var comment = '# Subtest'
if (p.name)
comment += ': ' + p.name
comment += '\n'
this.parser.write(comment)
cb()
}
Test.prototype.onbufferedend = function (p, er) {
delete p.ondone
p.results = p.results || {}
p.readyToProcess = true
var to = p.options.timeout
if (to && p.passing())
var dur = Date.now() - p.start
if (dur && dur > to)
p.timeout()
else
p.setTimeout(false)
this.debug('%s.onbufferedend', this.name, p.name, p.results.bailout)
this.pool.remove(p)
p.options.tapChildBuffer = p.output || ''
p.options.stack = ''
if (p.time)
p.options.time = p.time
if (this.occupied === p)
this.occupied = null
if (er)
this.threw(er)
p.deferred.resolve(this)
this.process()
}
Test.prototype.onindentedend = function (p, er) {
delete p.ondone
this.debug('onindentedend', p)
this.noparallel = false
var sti = this.subtests.indexOf(p)
if (sti !== -1)
this.subtests.splice(sti, 1)
p.readyToProcess = true
p.results = p.results || {}
if (p.time)
p.options.time = p.time
var to = p.options.timeout
if (to && p.passing())
var dur = Date.now() - p.start
if (dur && dur > to)
p.timeout()
else
p.setTimeout(false)
this.debug('onindentedend %s(%s)', this.name, p.name, er || 'ok')
assert(this.occupied === p)
this.occupied = null
this.debug('OIE(%s) b>shift into queue', this.name, this.queue)
p.options.stack = ''
this.queue.unshift(['emitSubTeardown', p])
this.printResult(p.passing(), p.name, p.options, true)
this.debug('OIE(%s) shifted into queue', this.name, this.queue)
if (er)
this.threw(er)
p.deferred.resolve(this)
this.process()
}
Test.prototype.addAssert = function (name, length, fn) {
if (!name)
throw new TypeError('name is required for addAssert')
if (!(typeof length === 'number' && length >= 0))
throw new TypeError('number of args required')
if (typeof fn !== 'function')
throw new TypeError('function required for addAssert')
if (Test.prototype[name] || this[name])
throw new TypeError('attempt to re-define `' + name + '` assert')
this[name] = function ASSERT () {
if (!this.currentAssert) {
this.currentAssert = ASSERT
}
var args = new Array(length + 2)
for (var i = 0; i < length; i++) {
args[i] = arguments[i]
}
if (typeof arguments[length] === 'object') {
args[length] = ''
args[length + 1] = arguments[length]
} else {
args[length] = arguments[length] || ''
args[length + 1] = arguments[length + 1] || {}
}
return fn.apply(this, args)
}
}
Test.prototype.fail = function fail (message, extra) {
if (!this.currentAssert) {
this.currentAssert = fail
}
if (message && typeof message === 'object') {
extra = message
message = ''
} else {
if (!message) {
message = ''
}
if (!extra) {
extra = {}
}
}
this.printResult(false, message, extra)
var ret = true
if (!extra.todo && !extra.skip)
ret = false
return ret
}
Test.prototype.pass = function pass (message, extra) {
if (!this.currentAssert) {
this.currentAssert = pass
}
this.printResult(true, message || '(unnamed test)', extra)
return true
}
Test.prototype.printResult = function pR (ok, message, extra, front) {
var n = this.count + 1
if (this.planEnd !== -1 && n > this.planEnd) {
if (!this.passing())
return
var failMessage = this.explicitEnded
? 'test after end() was called'
: 'test count exceeds plan'
var er = new Error(failMessage)
Error.captureStackTrace(er, this.currentAssert || pR)
er.test = this.name
er.plan = this.planEnd
this.threw(er)
return
}
extra = extra || {}
if (this.assertAt) {
extra.at = this.assertAt
this.assertAt = null
}
if (this.assertStack) {
extra.stack = this.assertStack
this.assertStack = null
}
if (hasOwn(extra, 'stack') && !hasOwn(extra, 'at'))
extra.at = stack.parseLine(extra.stack.split('\n')[0])
var fn = this.currentAssert || pR
this.currentAssert = null
if (!ok && !extra.skip && !hasOwn(extra, 'at')) {
assert.equal(typeof fn, 'function')
extra.at = stack.at(fn)
if (!extra.todo)
extra.stack = stack.captureString(80, fn)
}
var diagnostic
if (!ok)
diagnostic = true
if (extra.skip)
diagnostic = false
if (process.env.TAP_DIAG === '0')
diagnostic = false
if (typeof extra.diagnostic === 'boolean')
diagnostic = extra.diagnostic
if (diagnostic)
extra.diagnostic = true
this.count = n
var res = { ok: ok, message: message, extra: extra }
var output = new TestPoint(ok, message, extra)
// when we jump the queue, skip an extra line
if (front)
output.message = output.message.trimRight() + '\n\n'
if (front) {
this.emit('result', res)
this.parser.write(output.ok + (++this.n) + output.message)
} else
this.queue.push(['emit', 'result', res], output)
if (this.planEnd === this.count)
this.end(IMPLICIT)
this.process()
}
Test.prototype.pragma = function (set) {
var p = ''
Object.keys(set).forEach(function (i) {
p += 'pragma ' + (set[i] ? '+' : '-') + i + '\n'
})
this.queue.push(p)
this.process()
}
Test.prototype.plan = function (n, comment) {
if (this.bailedOut)
return
if (this.planEnd !== -1) {
throw new Error('Cannot set plan more than once')
}
if (typeof n !== 'number' || n < 0) {
throw new TypeError('plan must be a number')
}
// Cannot get any tests after a trailing plan, or a plan of 0
var ending = false
if (this.count !== 0 || n === 0) {
ending = true
}
if (n === 0)
this.skip = comment || true
this.planEnd = n
comment = comment ? ' # ' + comment.trim() : ''
this.queue.push('1..' + n + comment + '\n')
if (ending)
this.end(IMPLICIT)
else
this.process()
}
Test.prototype.done = Test.prototype.end = function (implicit) {
this.debug('END implicit=%j', implicit === IMPLICIT)
if (this.ended && implicit === IMPLICIT)
return
// beyond here we have to be actually done with things, or else
// the semantic checks on counts and such will be off.
if (!queueEmpty(this) || this.occupied) {
if (!this.pushedEnd)
this.queue.push(['end', implicit])
this.pushedEnd = true
return this.process()
}
if (!this.ranAfterEach && this.parent) {
this.ranAfterEach = true
this.parent.runAfterEach(this, end.bind(this, implicit))
} else
end.call(this, implicit)
}
function end (implicit) {
this.ended = true
if (implicit !== IMPLICIT && !this.multiEndThrew) {
if (this.explicitEnded) {
this.multiEndThrew = true
var er = new Error('test end() method called more than once')
Error.captureStackTrace(er, this.currentAssert || end)
er.test = this.name
this.threw(er)
return
}
this.explicitEnded = true
}
if (this.planEnd === -1) {
this.debug('END(%s) implicit plan', this.name, this.count)
this.plan(this.count)
}
this.queue.push(EOF)
this.process()
}
Test.prototype.threw = function (er, extra, proxy) {
this.debug('THREW', er.message, extra, proxy)
// event emitters 'error' events need to re-throw so that they
// can jump out of the flow like a normal throw. They'll just
// end up back here once that happens, though, unless there's a
// try/catch somewhere in the call stack.
if (er.domainEmitter) {
delete er.domainEmitter
throw er
}
if (this.name && !proxy)
er.test = this.name
if (!proxy)
extra = extraFromError(er, extra, this.options)
Base.prototype.threw.call(this, er, extra, proxy)
if (!this.results) {
this.fail(extra.message || er.message, extra)
if (!proxy)
this.end(IMPLICIT)
}
this.process()
}
Test.prototype.runBeforeEach = function (who, cb) {
var self = this
if (this.parent)
this.parent.runBeforeEach(who, function () {
loop(who, self.onBeforeEach, cb, who.threw)
})
else
loop(who, self.onBeforeEach, cb, who.threw)
}
Test.prototype.runAfterEach = function (who, cb) {
var self = this
loop(who, self.onAfterEach, function () {
if (self.parent)
self.parent.runAfterEach(who, cb)
else
cb()
}, who.threw)
}
Test.prototype.beforeEach = function (fn) {
this.onBeforeEach.push(fn)
}
Test.prototype.afterEach = function (fn) {
this.onAfterEach.push(fn)
}
Test.prototype.teardown = Test.prototype.tearDown = function (fn) {
this.on('teardown', fn)
}
Test.prototype.shouldAutoend = function () {
var should = (
this.options.autoend &&
!this.ended &&
!this.occupied &&
queueEmpty(this) &&
!this.pool.length &&
!this.subtests.length &&
this.planEnd === -1
)
return should
}
Test.prototype.autoend = function () {
this.options.autoend = true
this.maybeAutoend()
}
Test.prototype.maybeAutoend = function () {
if (this.autoendTimer)
clearTimeout(this.autoendTimer)
if (this.shouldAutoend()) {
var self = this
self.autoendTimer = setTimeout(function () {
if (self.shouldAutoend()) {
self.autoendTimer = setTimeout(function () {
if (self.shouldAutoend()) {
self.end(IMPLICIT)
}
})
}
})
}
}
function endAllQueue (queue) {
queue.forEach(function (p, i) {
if ((p instanceof Base) && !p.readyToProcess)
queue[i] = new TestPoint(false,
'child test left in queue ' + p.constructor.name + ': ' +
p.name, p.options)
})
queue.push(['end', IMPLICIT])
}
function queueEmpty (t) {
return t.queue.length === 0 ||
t.queue.length === 1 && t.queue[0] === 'TAP version 13\n'
}
Test.prototype.endAll = function (sub) {
this.processing = true
if (this.occupied) {
var p = this.occupied
if (p.endAll)
p.endAll(true)
else {
p.parser.abort('test unfinished')
}
} else if (sub) {
this.process()
if (queueEmpty(this)) {
var options = Object.keys(this.options).reduce(function (o, k) {
o[k] = this.options[k]
return o
}.bind(this), {})
this.options.at = null
this.options.stack = ''
options.test = this.name
this.fail('test unfinished', options)
}
}
if (this.promise && this.promise.tapAbortPromise)
this.promise.tapAbortPromise()
if (this.occupied) {
this.queue.unshift(this.occupied)
this.occupied = null
}
endAllQueue(this.queue)
this.processing = false
this.process()
this.parser.end()
}
// Add all the asserts
tapAsserts.decorate(Test.prototype)