0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-31 10:58:54 +01:00
construct/modules/static/js/debug.js
2017-12-24 19:26:05 -07:00

203 lines
4.9 KiB
JavaScript

/*
* IRCd Charybdis 5/Matrix
*
* Copyright (C) 2017 Charybdis Development Team
* Copyright (C) 2017 Jason Volk (jason@zemos.net)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
'use strict';
/**************************************
*
* Debugging tools
*
*/
/**
* Debugging and testing related suite. This provides a more friendly version
* of JSON.stringify() for debugging the contents of deep objects with formatting
* and a recursion limit specifier; also a convenience tie-in to console.log();
*
* ex:
* debug.object({foo: {bar: 'baz'}}, 2); // prints all content to console
* debug.object({foo: {bar: 'baz'}}, 1); // does not print members of foo
*/
const debug =
{
/** Recursive object stringification in pseudo-JSON
*
* @param {object} obj - Object to represent as string.
* @param {number} r_max - The maximum recursion depth.
* @param {number} r - The current frame's recursion depth.
* @returns {string} A string representation of the object.
*/
stringify(obj, r_max = 10, enumerator = Object.aeach, r = 1)
{
let tabular = (r, ret = "", i = 0) =>
{
for(; i < r; i++)
ret += "\t";
return ret;
};
let _object = (k, obj) =>
{
let n = empty(obj[k]);
let s = n? "{}" : this.stringify(obj[k], r_max, enumerator, r + 1);
return "\n" + tabular(r) + k + ": " + s + ',';
};
let _string = (k, obj) =>
"\n" + tabular(r) + k + ": " + obj[k] + ",";
let _function = (k) =>
"\n" + tabular(r) + k + "()" + ",";
switch(typeof(obj))
{
case "object":
break;
default:
return tabular(r - 1) + JSON.stringify(obj);
}
// Iterate and append the members of the object to the return string
// with recursion for objects/arrays if the max depth is not exceeded.
let ret = "\n" + tabular(r - 1) + "{";
let _property = (k) =>
{
switch(typeof(obj[k]))
{
case "object":
if(r < r_max)
{
ret += _object(k, obj);
break;
} // [[fallthrough]]
case "boolean":
case "number":
case "string":
ret += _string(k, obj);
break;
case "function":
ret += _function(k);
break;
}
};
enumerator(obj, (key) => _property(key));
return ret + "\n" + tabular(r - 1) + "}";
},
log(func, obj, r_max = 1, enumerator = Object.aeach)
{
func(this.stringify(obj, r_max, enumerator));
},
/** Stringify to console.log() */
object(obj, r_max = 2, enumerator = Object.aeach)
{
this.log(console.log, obj, r_max, enumerator);
},
/** Stringify to console.error() */
error(obj, r_max = 2, enumerator = Object.aeach)
{
this.log(console.error, obj, r_max, enumerator);
},
/** Convenience Node.js style callback function to pass as the callback
* argument which prints the resulting object for viewing in the console.
*/
callback(error, data)
{
let obj = error !== undefined? error : data;
let text = debug.stringify(obj, 2);
if(error !== undefined)
console.error(text);
else
console.log(text);
},
/** TODO: XXX
* To debug Angular model updating.
*/
digest(name, $scope)
{
let wc = $scope.$$watchersCount;
let watchers = " $$watchersCount: " + wc;
console.log("$digest() #" + $scope.$id + " '" + name + "'" + watchers);
},
};
/** Convenience because I keep typing it
*/
Object.debug = function(...obj)
{
return debug.object(...obj);
};
/**
*/
function stacktrace()
{
function _stacktrace(caller)
{
if(!caller)
return [];
const name = caller.toString();
const args = caller.arguments.join(',');
const rep = name.split('(')[0].substring(9) + '(' + args + ')';
return _stacktrace(caller.caller).concat([rep]);
}
return _stacktrace(arguments.callee.caller);
}
/** convenience stub
*/
function test(value = undefined, quiet = false)
{
switch(typeof(value))
{
case "undefined":
if(!quiet) console.log("test undefined");
return true;
case "string":
case "boolean":
if(!quiet) console.log("test " + value);
return value;
case "function":
quiet? value() : console.log("test[F] " + value());
default:
if(!quiet) console.log("test: " + JSON.stringify(value));
return true;
}
}