Editing Belt Error Perf This edit will create a new revision. Your details (optional) Name Email (won’t be displayed; might be used for Gravatar) URL Test case details Title * Published (uncheck if you want to fiddle around before making the page public) Description (in case you feel further explanation is needed)(Markdown syntax is allowed) Are you a spammer? (just answer the question) Preparation code Preparation code HTML (this will be inserted in the <body> of a valid HTML5 document in standards mode) (useful when testing DOM operations or including libraries) Include JavaScript libraries as follows: <script src="//cdn.ext/library.js"></script> Define setup for all tests (variables, functions, arrays or other objects that will be used in the tests) (runs before each clocked test loop, outside of the timed code region) (e.g. define local test variables, reset global variables, clear canvas, etc.) (see FAQ) /* * belt.js * * A general-purpose utility function. Used to extend * and house my general-purpose js-utils. * */ (function(global) { /* * SETUP * * Initialize public and private variables, and overwrite * the `global.BELT` namespace, caching anything that might be there. * Orient document, navigator, location to the global object, since we're * operating inside a self-invoking function closure. * * BELT : Global namespace for utility functions. * * _cache : A private cache object accessed by BELT fns. * _errors : A private error queue; populated by BELT error logging. * _belt : A copy of anything in the `global.BELT` namespace, in case * we end up overwriting something. * _console : A copy of the `global.console` if it exists. BELT defaults to * creating a safe copy of console in the global namespace, * overwriting the normal `global.console`. * */ var BELT = {}, _cache = {}, _errors = [], // Make sure document, location, navigator are properly defined // within the scope of this self-invoking function. document = global.document, location = global.location, navigator = global.navigator; // Since we'll be overwriting global.BELT and global.console // make the old values accessible via the _cache. _cache.global_BELT = global.BELT; _cache.global_console = global.console; /* ---------------- top ----------------- */ /* * CORE JS UTILITIES * * Borrow various native functions for internal use. * Any self-rolled object and array manipulation functions go here. * * slice() * Array.prototype.slice * * push() * Array.prototype.push * * toString() * Object.prototype.toString * * hasOwnProperty() * Object.prototype.hasOwnProperty * * isArray() * Checks if the thing passed in is an array. * @arguments : something * @return : [boolean] * * isObject() * Checks if the thing passed in is an object. * @arguments : something * @return : [boolean] * * clone() * Create a deep copy of an object via recursion. * This is more effective than JSON.* means of cloning objects, * since cloned functions are usable. * This is for non-prototypal object literals and arrays, rather * than constructed objects... for the moment. * Currently outstrips jQuery.extend() [v 1.8.3] in performance * by a significant margin : http://jsperf.com/belt-core-deep-clone * @arguments : from [,to] * @return : [clone of object] * * namespace() * Return the tip of a namespace. If it doesn't exist yet, then * create an object in this namespace. * Using `BELT.namespace()` prevents accidental rewrites when * working with big namespaces. * @arguments : [string] * @return : [Object object] * * inherit() * A simple inheritance function. * @arguments : parent, child / * {parent:, child:} * @return : ... * * extend() * @arguments : obj, extendWithProperties * @return : boolean * * createConsoleAlias() * The JavaScript global console object is not consistently implemented * cross brwoser yet. * This creates a `console` object to prevent script crashes when you * attempt to access a method of an undefined object. Methods are aliased * in stages based on browser availability. * As far as I know, I've grouped the commands by availability in different * browser environments. The most generic set, `ie_opera_ff_webkit` will * work pretty reliably x-browser when you use it. * @arguments : none * @return : Pseudo-console. * */ (function defineCoreModule(BELT) { BELT.core = {}; BELT.slice = BELT.core.slice = Array.prototype.slice; BELT.push = BELT.core.push = Array.prototype.push; BELT.toString = BELT.core.toString = Object.prototype.toString; BELT.hasOwnProperty = BELT.core.hasOwnProperty = Object.prototype.hasOwnProperty; BELT.isArray = BELT.core.isArray = function(it) { return (it instanceof Array); }; BELT.isObject = BELT.core.isObject = function(it) { return (typeof it === 'object'); }; BELT.clone = BELT.core.clone = (function() { // Private helper function for public clone() API. function recurse(from_i, doppel_i) { if (BELT.core.isArray(from_i) || BELT.core.isObject(from_i)) { return BELT.core.clone(from_i, doppel_i); } else { return from_i; } } return function(from, to) { var doppel, i; if (BELT.core.isArray(from)) { doppel = to || []; for (i = 0; i < from.length; i += 1) { doppel[i] = recurse(from[i], doppel[i]); } } else if (BELT.core.isObject(from)) { doppel = to || {}; for (i in from) { doppel[i] = recurse(from[i], doppel[i]); } } else { doppel = from; } return doppel; }; }()); BELT.namespace = BELT.core.namespace = function(str) { var levels = str && str.split && str.split('.'), i = 0, name_space, step, msg; // Fallthrough if incorrect usage. if (levels === undefined) { msg = 'BELT.namespace(str) : str can\'t be ' + str; throw new Error(msg); } // Find the namespace (should be first str.) name_space = levels[0]; step = global[levels[0]] || (global[levels[0]] = {}); levels.shift(); // Iterate through the levels of the namespace string. for (; i < levels.length; i += 1) { if (typeof step[levels[i]] === 'undefined') { step[levels[i]] = {}; } else if (typeof step[levels[i]] === 'function') { i += 1; msg = 'BELT.namespace() : ' + name_space + '.'; msg += levels.slice(0, i).join('.') + ' is a function'; throw new Error(msg); } step = step[levels[i]]; } return step; }; BELT.inherit = BELT.core.inherit = function inherit(P, C) { var opt = typeof P === 'object' ? P : {parent:P, child:C}, F = function() {}; F.prototype = opt.parent.prototype; opt.child.prototype = new F(); opt.child.prototype_chain = opt.parent.prototype_chain || []; opt.child.prototype_chain.push(opt.parent.prototype); opt.child.prototype.constructor = opt.child; }; // How to use to write plugins: // BELT.extend(BELT.namespace('ns'), { props }); BELT.extend = BELT.core.extend = function(obj, extendWithProperties) { console.error('WARNING: BELT.extend() incomplete.'); }; BELT.core.createConsoleAlias = function(){ var new_console = new function BELTConsole() {}, g_console = BELT.storage.get('global_console'), method_groups = { ie_opera_ff_webkit: ['log', 'warn', 'error', 'info', 'assert', 'clear'], opera_ff_webkit: ['dir', 'trace', 'profile', 'profileEnd', 'group', 'groupEnd'], ff_webkit: ['debug', 'groupCollapsed', 'time', 'timeEnd', 'noSuchMethod'], webkit: ['timeStamp', 'markTimeline', 'dirxml'] }, group, method, fn, i; for (group in method_groups) { for (i = 0; i < method_groups[group].length; i += 1) { new_console[method_groups[group][i]] = (function(method) { // Must be called directly on console object, otherwise you // have IllegalInvocation errors. if (g_console[method]) { fn = function(a) { g_console[method](a) }; } else if (g_console['log']) { fn = function(a) { g_console['log'](a) }; } else { fn = function(){}; } return fn; }(method_groups[group][i])); } } // Allow direct access to private Webkit Console APIs that aren't methods. new_console.memory = g_console.memory || {}; new_console.profiles = g_console.profiles || {}; // Return aliased functions. return new_console; }; }(BELT)); /* * PROBLEM * * Error handling for your JS app. * * reportProblem() * Used for logging problems. ...? * @arguments : message [, type][, fn_name] * { message:, [,type:] [,fn_name:] } * @return : * * Err * @arguments : message [, fn_name] * { message: [, fn_name:] } */ (function defineProblemModule(BELT) { BELT.problem = {}; // namespace. // Public API. BELT.reportProblem = BELT.problem.report = function(message, type, fn_name) { var opt = (typeof message === 'object') ? message : {message: message, type: type, fn_name: fn_name}; // Mandatory Arg: message. opt.message === undefined && BELT.problem.report({ /* !!! Error message API */ }); // Processing ... console.error('Error: BELT.problem.report() incomplete.'); }; // Constructors. BELT.problem.Error = function(message, fn_name) { var opt = typeof message === 'object' ? message : { message: message, fn_name: fn_name }; this.type = 'Error'; this.name = this.constructor.name || 'Error'; this.message = opt.message || 'Unhelpful generic error.'; this.timestamp = BELT.date.timestamp(); this.navigator_raw = global.navigator || 'Unavailable.'; this.location_raw = global.location || 'Unavailable.'; }; BELT.core.inherit(global.Error, BELT.problem.Error); }(BELT)); /* * STORAGE (CACHE) * * storage.set() * Set a key-value pair in the private _cache object. * @arguments : key, value / {key:, value:} * @returns : true if success * * storage.get() * Retreive an item from the private _cache object. * @arguments : key [string] / [empty] * @return : _cache.key / clone of _cache * */ (function defineStorageModule(BELT) { BELT.storage = {}; BELT.storage.set = function(key, value) { var opt = (typeof key === 'object') ? key : {key: key, value: value}; // Arg checking: overkill, but better than losing data. opt.key === undefined && BELT.problem.report({/* !!! Error message API */}); typeof opt.key !== 'string' && BELT.problem.report({ /* !!! Error message API */}); opt.value === undefined && BELT.problem.report({ /* !!! Error message API */ }); // Set to private cache. _cache[opt.key] = opt.value; }; BELT.storage.get = function(key) { if (key) { return _cache[key] } else { return BELT.core.clone(_cache) } }; }(BELT)); /* * DATE * * General purpose date handling module. * Among other things, it shims `Date.now()` if it is not supported by * the browser. * `new Date().getTime()` outperforms `+(new Date)` by a fairly large margin, * so that's the chosen shim. http://jsperf.com/creating-timestamps * * timestamp() * Returns a unix timestamp. * */ (function defineDateModule(BELT) { BELT.date = {}; // Shim for older ECMA (sub 1.5) engines. Date.now = Date.now || function now() {return new Date().getTime() }; BELT.timestamp = BELT.date.timestamp = function() { return Math.floor(Date.now() / 1000); }; }(BELT)); /* ----------- bottom ------------- */ /* * EXPOSE/EXPORT * * Create a safe console alias. * * Expose local BELT variable to the global namespace, based on the * global variable passed into this self-invoking function. * */ global.console = BELT.core.createConsoleAlias(); global.BELT = BELT; }(window)); // Will either be GLOBAL (node) || window (browser) Define teardown for all tests (runs after each clocked test loop, outside of the timed code region) (see FAQ) Code snippets to compare Test 1 Title Async (check if this is an asynchronous test) Code var e = new BELT.problem.Error('I am an error.'); Test 2 Title Async (check if this is an asynchronous test) Code var e = new Error('I am an error.');