118 lines
2.6 KiB
JavaScript
118 lines
2.6 KiB
JavaScript
const { inherits } = require('util')
|
|
|
|
function Reporter (options) {
|
|
this._reporterState = {
|
|
obj: null,
|
|
path: [],
|
|
options: options || {},
|
|
errors: []
|
|
}
|
|
}
|
|
|
|
Reporter.prototype.isError = function isError (obj) {
|
|
return obj instanceof ReporterError
|
|
}
|
|
|
|
Reporter.prototype.save = function save () {
|
|
const state = this._reporterState
|
|
|
|
return { obj: state.obj, pathLen: state.path.length }
|
|
}
|
|
|
|
Reporter.prototype.restore = function restore (data) {
|
|
const state = this._reporterState
|
|
|
|
state.obj = data.obj
|
|
state.path = state.path.slice(0, data.pathLen)
|
|
}
|
|
|
|
Reporter.prototype.enterKey = function enterKey (key) {
|
|
return this._reporterState.path.push(key)
|
|
}
|
|
|
|
Reporter.prototype.exitKey = function exitKey (index) {
|
|
const state = this._reporterState
|
|
|
|
state.path = state.path.slice(0, index - 1)
|
|
}
|
|
|
|
Reporter.prototype.leaveKey = function leaveKey (index, key, value) {
|
|
const state = this._reporterState
|
|
|
|
this.exitKey(index)
|
|
if (state.obj !== null) { state.obj[key] = value }
|
|
}
|
|
|
|
Reporter.prototype.path = function path () {
|
|
return this._reporterState.path.join('/')
|
|
}
|
|
|
|
Reporter.prototype.enterObject = function enterObject () {
|
|
const state = this._reporterState
|
|
|
|
const prev = state.obj
|
|
state.obj = {}
|
|
return prev
|
|
}
|
|
|
|
Reporter.prototype.leaveObject = function leaveObject (prev) {
|
|
const state = this._reporterState
|
|
|
|
const now = state.obj
|
|
state.obj = prev
|
|
return now
|
|
}
|
|
|
|
Reporter.prototype.error = function error (msg) {
|
|
let err
|
|
const state = this._reporterState
|
|
|
|
const inherited = msg instanceof ReporterError
|
|
if (inherited) {
|
|
err = msg
|
|
} else {
|
|
err = new ReporterError(state.path.map(function (elem) {
|
|
return `[${JSON.stringify(elem)}]`
|
|
}).join(''), msg.message || msg, msg.stack)
|
|
}
|
|
|
|
if (!state.options.partial) { throw err }
|
|
|
|
if (!inherited) { state.errors.push(err) }
|
|
|
|
return err
|
|
}
|
|
|
|
Reporter.prototype.wrapResult = function wrapResult (result) {
|
|
const state = this._reporterState
|
|
if (!state.options.partial) { return result }
|
|
|
|
return {
|
|
result: this.isError(result) ? null : result,
|
|
errors: state.errors
|
|
}
|
|
}
|
|
|
|
function ReporterError (path, msg) {
|
|
this.path = path
|
|
this.rethrow(msg)
|
|
}
|
|
inherits(ReporterError, Error)
|
|
|
|
ReporterError.prototype.rethrow = function rethrow (msg) {
|
|
this.message = `${msg} at: ${this.path || '(shallow)'}`
|
|
if (Error.captureStackTrace) { Error.captureStackTrace(this, ReporterError) }
|
|
|
|
if (!this.stack) {
|
|
try {
|
|
// IE only adds stack when thrown
|
|
throw new Error(this.message)
|
|
} catch (e) {
|
|
this.stack = e.stack
|
|
}
|
|
}
|
|
return this
|
|
}
|
|
|
|
exports.Reporter = Reporter
|