UNPKG

preceptor-core

Version:

Core components for the preceptor test runner and aggregator

178 lines (160 loc) 4.64 kB
// Copyright 2014-2015, Yahoo! Inc. // Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms. var _ = require('underscore'); /** * @class utils */ /** * An extend function that applies the result of a callback to each item * * @method extendApply * @param {object} obj Destination object to merge into * @param {object[]} objects Objects that should get merged into the destination object * @param {function} [fn] Apply function for each item, returning the final result * @return {object} Destination object */ var extendApply = function (obj, objects, fn) { fn = fn || function (item /* , previousItem, obj, objectIndex, valueIndex */) { return item; }; objects.forEach(function (currentObject, objectIndex) { if (currentObject) { _.keys(currentObject).forEach(function (key, valueIndex) { obj[key] = fn(currentObject[key], obj[key], { key: key, currentObject: currentObject, objectIndex: objectIndex, valueIndex: valueIndex }); }); } }); return obj; }; /** * Deep-extend of an object * * @method deepExtend * @param {object} obj * @param {object[]} objects * @param {object} [options] * @param {boolean} [options.replace=false] * @return {object} */ var deepExtend = function (obj, objects, options) { options = options || {}; objects.forEach(function (currentObject) { if (currentObject) { _.keys(currentObject).forEach(function (key) { var i, len; if ((_.isArray(obj[key]) || !obj[key]) && _.isArray(currentObject[key])) { if (options.replace) { obj[key] = deepExtend(obj[key] || [], [currentObject[key]]); } else { obj[key] = (obj[key] || []); for (i = 0, len = currentObject[key].length; i < len; i++) { if (_.isArray(currentObject[key][i])) { obj[key].push(deepExtend([], [currentObject[key][i]])); } else if (_.isObject(currentObject[key][i])) { obj[key].push(deepExtend({}, [currentObject[key][i]])); } else { obj[key].push(currentObject[key][i]); } } } } else if (_.isFunction(currentObject[key])) { obj[key] = currentObject[key]; } else if ((_.isObject(obj[key]) || !obj[key]) && _.isObject(currentObject[key])) { obj[key] = deepExtend(obj[key] || {}, [currentObject[key]]); } else { obj[key] = currentObject[key]; } }); } }); return obj; }; /** * Wraps a function into another function that sets another function as the __super() function * This is used to wrap every single function of an object so that one can call * * this.__super(); * * to call its parent function that was overwritten. * * @method superWrapper * @param {*} currentItem * @param {*} previousItem * @return {*} */ var superWrapper = function (currentItem, previousItem) { if (_.isFunction(currentItem) && (!previousItem || _.isFunction(previousItem))) { previousItem = previousItem || function () { }; return function () { var result, self = this, oldSuper = self.__super; self.__super = function () { return previousItem.apply(self, arguments); }; result = currentItem.apply(self, arguments); self.__super = oldSuper; return result; }; } else { return currentItem; } }; /** * Combines multiple strings into one, making sure that the glue-string doesn't get applied when not required * * @method combine * @param {string} glue * @param {string} str1 * @return {string} */ var combine = function (glue, str1 /*, ... */) { var args = Array.prototype.slice.call(arguments, 2), result = str1; args.forEach(function (arg) { if ((result.substr(-1) === glue) && (arg.substr(0, 1) === glue)) { result += arg.substr(1); } else if ((result.substr(-1) === glue) || (arg.substr(0, 1) === glue)) { result += arg; } else { result += glue + arg; } }); return result; }; /** * Turns a string into a filesystem safe filename * * @method fileNameSafe * @param {string} str * @return {string} */ var fileNameSafe = function (str) { return str.replace(/[^a-zA-Z\d]/g, '-'); }; /** * Safely requires a module * * @method require * @param {string} module Module name or path * @param {*} [defaultValue] Default value if the module cannot be found * @return {*} */ var requir = function (module, defaultValue) { try { return require(module); } catch (err) { if (defaultValue === undefined) { throw new Error("Cannot find module: " + module); } return defaultValue; } }; module.exports = { superWrapper: superWrapper, extendApply: extendApply, deepExtend: deepExtend, combine: combine, fileNameSafe: fileNameSafe, require: requir };