|
Overview
|
Coverage99.91
SLOC12327
LOC3358
Missed3
|
|
base/functions.js
|
Coverage99.03
SLOC279
LOC103
Missed1
|
- 1
var string = require("./string"),object = require("./object"),isArray = Array.isArray,isObject = object.isObject,isString = string.isString;/*** Determines if something is a function* @param {Anything} obj the thing to test if it is a function** @returns {Boolean} true if the obj is a function false otherwise* @static* @memberOf comb*/- 1
function isFunction(obj) {- 30832
return typeof obj === "function";}/*** Binds a method to a particular scope** @static* @memberOf comb** @param {Object} scope the scope to bind the callback to* @param {String|Function} method the method to callback* @param [args] optional args to pass to the callback** @returns {Function} the hitched function*/- 1
function hitch(scope, method, args) {- 5486
args = Array.prototype.slice.call(arguments).slice(2);- 5486
if ((isString(method) && !(method in scope))) {- 2
throw new Error(method + " property not defined in scope");- 5484
} else if (!isString(method) && !isFunction(method)) {- 1
throw new Error(method + " is not a function");}- 5483
if (isString(method)) {- 452
return function () {- 541
var func = scope[method];- 541
if (isFunction(func)) {- 538
var scopeArgs = args.concat(Array.prototype.slice.call(arguments));- 538
return func.apply(scope, scopeArgs);} else {- 3
return func;}};} else {- 5031
return function () {- 4290
var scopeArgs = args.concat(Array.prototype.slice.call(arguments));- 4290
return method.apply(scope, scopeArgs);};}}/*** Binds a method to the scope of the first argument.** This is useful if you have async actions and you just want to run a method or retrieve a property on the object.** ```* var arr = [], push = comb.applyFirst("push"), length = comb.applyFirst("length");* push(arr, 1, 2,3,4);* console.log(length(arr)); //4* console.log(arr); //1,2,3,4** ```* @static* @memberOf comb* @param {String|Function} method the method to invoke in the scope of the first arument.* @param [args] optional args to pass to the callback** @returns {Function} a function that will execute the method in the scope of the first argument.*/- 1
function applyFirst(method, args) {- 10
args = Array.prototype.slice.call(arguments).slice(1);- 10
if (!isString(method) && !isFunction(method)) {- 2
throw new Error(method + " must be the name of a property or function to execute");}- 8
if (isString(method)) {- 4
return function () {- 12
var scopeArgs = Array.prototype.slice.call(arguments), scope = scopeArgs.shift();- 12
var func = scope[method];- 12
if (isFunction(func)) {- 6
scopeArgs = args.concat(scopeArgs);- 6
return func.apply(scope, scopeArgs);} else {- 6
return func;}};} else {- 4
return function () {- 4
var scopeArgs = Array.prototype.slice.call(arguments), scope = scopeArgs.shift();- 4
scopeArgs = args.concat(scopeArgs);- 4
return method.apply(scope, scopeArgs);};}}- 1
;/*** @function* Binds a method to a particular scope* @static* @memberOf comb* @param {Object} scope the scope to bind the callback to* @param {String|Function} method the method to callback* @param [args] optional args to pass to the callback** @returns {Function} the hitched function*/- 1
exports.bind = hitch;/*** Binds a method to a particular scope ignoring any new arguments passed* into the function. This is useful if you want to force particular arguments and* ignore any new ones* @static* @memberOf comb* @param {Object} scope the scope to bind the callback to* @param {String|Function} method the method to callback* @param [args] optional args to pass to the callback** @returns {Function} the hitched function*/- 1
function hitchIgnore(scope, method, args) {- 136
args = Array.prototype.slice.call(arguments).slice(2);- 136
if ((isString(method) && !(method in scope))) {- 2
throw new Error(method + " property not defined in scope");- 134
} else if (!isString(method) && !isFunction(method)) {- 1
throw new Error(method + " is not a function");}- 133
if (isString(method)) {- 15
return function () {- 15
var func = scope[method];- 15
if (isFunction(func)) {- 12
return func.apply(scope, args);} else {- 3
return func;}};} else {- 118
return function () {- 107
return method.apply(scope, args);};}}/*** @function* Binds a method to a particular scope ignoring any new arguments passed* into the function. This is useful if you want to force particular arguments and* ignore any new ones* @static* @memberOf comb* @param {Object} scope the scope to bind the callback to* @param {String|Function} method the method to callback* @param [args] optional args to pass to the callback** @returns {Function} the hitched function*/- 1
exports.bindIgnore = hitchIgnore;- 1
function hitchAll(scope, methods) {- 3
var funcs = Array.prototype.slice.call(arguments).slice(1);- 3
if (!isObject(scope)) {- 0
throw new TypeError("scope must be an object");}- 3
if (funcs.length === 1 && isArray(funcs[0])) {- 1
funcs = funcs[0];}- 3
if (!funcs.length) {- 1
funcs = Object.keys(scope).filter(function (k) {- 6
return isFunction(scope[k]);});}- 3
for (var i = 0, l = funcs.length; i < l; i++) {- 6
scope[funcs[i]] = hitch(scope, scope[funcs[i]]);}- 3
return object;}- 1
exports.hitchAll = hitchAll;- 1
exports.bindAll = hitchAll;/*** Allows the passing of additional arguments to a function when it is called* especially useful for callbacks that you want to provide additional parameters to** @static* @memberOf comb* @param {String|Function} method the method to callback* @param {Anything} [args] variable number of arguments to pass** @returns {Function} partially hitched function*/- 1
function partial(method, args) {- 8416
args = Array.prototype.slice.call(arguments).slice(1);- 8416
if (!isString(method) && !isFunction(method)) {- 2
throw new Error(method + " must be the name of a property or function to execute");}- 8414
if (isString(method)) {- 4
return function () {- 4
var func = this[method];- 4
if (isFunction(func)) {- 2
var scopeArgs = args.concat(Array.prototype.slice.call(arguments));- 2
return func.apply(this, scopeArgs);} else {- 2
return func;}};} else {- 8410
return function () {- 1697
var scopeArgs = args.concat(Array.prototype.slice.call(arguments));- 1697
return method.apply(this, scopeArgs);};}}- 1
;- 1
function curryFunc(f, execute) {- 28
return function (arg) {- 28
var args = Array.prototype.slice.call(arguments);- 28
return execute ? f.apply(this, arguments) : function (arg) {- 21
return f.apply(this, args.concat(Array.prototype.slice.call(arguments)));};};}/*** Curries a function* @example* var curried = comb.curry(4, function(a,b,c,d){* return [a,b,c,d].join(",");* }* curried("a");* curried("b");* curried("c");* curried("d") => "a,b,c,d"** //OR** curried("a")("b")("c")("d") => "a,b,c,d"** @static* @memberOf comb* @param {Number} depth the number of args you expect* @param {Function} cb the function to call once all args are gathered* @param {Object} [scope] what scope to call the function in** @returns {Function} the curried version of the function* */- 1
function curry(depth, cb, scope) {- 7
var f;- 7
if (scope) {- 5
f = hitch(scope, cb);} else {- 2
f = cb;}- 7
if (depth) {- 7
var len = depth - 1;- 7
for (var i = len; i >= 0; i--) {- 28
f = curryFunc(f, i === len);}}- 7
return f;}- 1
exports.isFunction = isFunction;- 1
exports.hitch = hitch;- 1
exports.hitchIgnore = hitchIgnore;- 1
exports.partial = partial;- 1
exports.applyFirst = applyFirst;- 1
exports.bindFirst = applyFirst;- 1
exports.curry = curry;
|
logging/index.js
|
Coverage99.39
SLOC678
LOC163
Missed1
|
- 1
var os = require("os"),define = require("../define.js"),base = require("../base"),isString = base.isString,merge = base.merge,isUndefinedOrNull = base.isUndefinedOrNull,isHash = base.isHash,isInstanceOf = base.isInstanceOf,argsToArray = base.argsToArray,format = base.string.format,Level = require("./level"),appenders = require("./appenders"),Appender = appenders.Appender,configurators = require("./config");- 1
var rootTree;- 1
var LoggerTree = define.define(null, {instance: {constructor: function (root) {- 14
this.__root = root;- 14
this.__name = root.name;- 14
this.__level = root.level;- 14
this.__parent = root._parent;- 14
this.__map = {};},__getSubLoggers: function () {- 6
var map = this.__map, ret = [], n;- 6
for (var i in map) {- 2
n = map[i];- 2
if (n) {- 2
ret = ret.concat(n.tree.getCurrentLoggers());}}- 6
return ret;},__getLoggers: function () {- 4
return [this.__root].concat(this.__getSubLoggers())},getCurrentLoggers: function () {- 4
return this.__getLoggers();},getSubLoggers: function () {- 2
return this.__getSubLoggers();},getLogger: function (name) {- 31
var ret;- 31
if (name) {- 29
var parts = name.split(".");- 29
if (parts.length) {- 29
var category = parts.shift();- 29
var lNode = this.__map[category];- 29
if (!lNode) {- 13
lNode = this.__map[category] = new Logger(category, this);- 13
lNode.addAppenders(this.__root.appenders);}- 29
ret = lNode;- 29
if (parts.length) {//keep searching- 10
name = parts.join(".");- 10
ret = lNode.tree.getLogger(name);}}} else {- 2
ret = this.__root;}- 31
return ret;},getRootLogger: function () {- 11
return this.__root;},isDisabled: function (level) {},resetConfiguration: function () {},/*** level = string|Level*/addAppender: function (appender) {- 63
var map = this.__map;- 63
for (var i in map) {- 41
map[i].addAppender(appender);}},removeAppender: function (name) {- 46
var map = this.__map;- 46
for (var i in map) {- 39
map[i].removeAppender(name);}},setters: {level: function (level) {- 45
this.__level = level;- 45
if (level && level instanceof Level) {- 45
var map = this.__map;- 45
for (var i in map) {- 2
map[i].level = level;}}}},getters: {categories: function () {- 2
return this.getCurrentLoggers().map(function (l) {- 3
return l.fullName;});},name: function () {- 35
var ret = this.__name;- 35
if (this.__parent) {- 21
var pName = this.__parent.name;- 21
if (pName) {- 8
ret = pName + "." + ret;}}- 35
return ret;},level: function () {- 13
return this.__level;},additive: function () {- 13
return this.__root.additive;}}}});- 1
var comb = exports;/*** @ignore* @namespace logging package*/- 1
comb.logging = merge({Level: Level}, configurators);/*** @ignore* @namespace appenders for logging*/- 1
comb.logging.appenders = appenders;- 1
var logging = comb.logging, hasGetGid = process.hasOwnProperty("getgid");/*** @class This class is the entry point for all logging actions in comb.* <p><b>Logger should be retrieved by calling Logger.getLogger() NOT through the new keyword</b><p>* <p>* All loggers in comb follow a heirarchy of inheritance based on a dot notation.* <pre class="code">* rootLogger - ""* / \* "my" "myOther"* / \* "my.logger" "myOther.logger"* / \* "my.logger.Log" "myOther.logger.Log"** </pre>* In the above Tree the rootLogger is the base for all logger. my and myOther inherit from rootLogger* my.logger inherits from my, and myOther.logger inherits from myOther. The logs do not have to be retrieved in* order. If I set rootLogger to ERROR level and added a console appender to it the appender and level will be* added to all logs. However if I set my to INFO level and add a fileAppender to it the level and appender will* only be added to logs in "my" subtree. If you set my.logger to not be additive then levels, and appenders will not* propogate down to the rest of the tree.** </p>** <p>For information on levels see {@link comb.logging.Level}.</p>* <p>For information on appenders see* <ul>* <li>{@link comb.logging.appenders.Appender}</li>* <li>{@link comb.logging.appenders.ConsoleAppender}</li>* <li>{@link comb.logging.appenders.FileAppender}</li>* <li>{@link comb.logging.appenders.JSONAppender}</li>* <li>{@link comb.logging.appenders.RollingFileAppender}</li>* </ul>* </p>* <p>For information on configurators see {@link comb.logging.BasicConfigurator} or {@link comb.logging.PropertyConfigurator}.</p>** @example** var logger = comb.logger;** //configure you logging environement* logger.configure();** //add a file appender to all loggers* logger.configure(logger.appender("FileAppender", {file : "/var/log/myLog.log"});** //Retreiving a logger.* var combLogger = logger("comb");* var combCollectionLogger = logger("comb.collections");* var treeLogger = logger("comb.collections.Tree")* //add a JSON appender to tree logger just for fun!* .addAppender("JSONAppender", {file : "/var/log/myTreeLogger.json"})** //set my treeLogger to DEBUG Level* treeLogger.level = "DEBUG";*** @name Logger* @memberOf comb.logging** @property {Array<comb.logging.Logger>} subLoggers all loggers this logger is the parent of.* @property {comb.logging.Level} level the level of this Logger* @property {Boolean} additive set to false to prevent changes to this logger from propogating down.* @property {Boolean} isDebug true if this Loggers level is DEBUG* @property {Boolean} isTrace true if this Loggers level is TRACE* @property {Boolean} isInfo true if this Loggers level is INFO* @property {Boolean} isWarn true if this Loggers level is WARN* @property {Boolean} isError true if this Loggers level is ERROR* @property {Boolean} isFatal true if this Loggers level is FATAL* @property {Boolean} isOff true if this Loggers level is OFF* @property {String} name the name of this logger this <b>does not</b> include the dot notated name* @property {String} fullName the full path name of this Logger.* @property {comb.logging.appenders.Appender} appenders list of appenders this logger currently contains.* @ignoreCode*/- 1
var Logger = (logging.Logger = define.define(null, {instance: {/**@lends comb.logging.Logger.prototype*/constructor: function (name, parent) {- 14
this.__additive = true;- 14
this.__name = name;- 14
this._parent = parent;- 14
this._tree = new LoggerTree(this);- 14
this.fullName = this._tree.name;- 14
if (!parent || !parent.additive) {- 1
this.level = Level.ALL;} else {- 13
this.level = parent.level;}- 14
this.__appenders = {};},/*** Log an info level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/info: function (message) {- 17
return this.log.apply(this, [Level.INFO].concat(argsToArray(arguments)));},/*** Log an debug level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/debug: function (message) {- 14
return this.log.apply(this, [Level.DEBUG].concat(argsToArray(arguments)));},/*** Log an error level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/error: function (message) {- 14
return this.log.apply(this, [Level.ERROR].concat(argsToArray(arguments)));},/*** Log an warn level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/warn: function (message) {- 14
return this.log.apply(this, [Level.WARN].concat(argsToArray(arguments)));},/*** Log an trace level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/trace: function (message) {- 14
return this.log.apply(this, [Level.TRACE].concat(argsToArray(arguments)));},/*** Log an fatal level message** @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/fatal: function (message) {- 14
return this.log.apply(this, [Level.FATAL].concat(argsToArray(arguments)));},/*** Creates a log event to be passed to appenders** @param {comb.logging.Level} level the level of the logging event* @param {String} message the message to be logged* @return {Object} the logging event*/getLogEvent: function getLogEvent(level, message) {- 64
return {hostname: os.hostname(),pid: process.pid,gid: hasGetGid ? process.getgid() : null,processTitle: process.title,level: level,levelName: level.name,message: message,timeStamp: new Date(),name: this.fullName};},/*** Log a message** @param {comb.logging.Level} level the level the message is* @param {String} message the message to log.** @return {comb.logging.Logger} for chaining.*/log: function (level, message) {- 93
var args = argsToArray(arguments, 1);- 93
level = Level.toLevel(level);- 93
if (args.length > 1) {- 18
message = format.apply(null, args);}- 93
if (level.isGreaterOrEqualToo(this.level)) {- 63
if (Level.TRACE.equals(level)) {- 10
var err = new Error;- 10
err.name = "Trace";- 10
err.message = message || '';- 10
Error.captureStackTrace(err, arguments.callee);- 10
message = err.stack;- 53
} else if (Level.ERROR.equals(level) && isInstanceOf(message, Error)) {- 0
message = message.stack;}- 63
var type = level.name.toLowerCase(), appenders = this.__appenders;- 63
var event = this.getLogEvent(level, message);- 63
Object.keys(appenders).forEach(function (i) {- 63
appenders[i].append(event);});}- 93
return this;},/*** Add an appender to this logger. If this is additive then the appender is added to all subloggers.** @example* comb.logger("my.logger")* .addAppender("ConsoleAppender")* .addAppender("FileAppender", {file:'/var/log/my.log'})* .addAppender("RollingFileAppender", {file:'/var/log/myRolling.log'})* .addAppender("JSONAppender", {file:'/var/log/myJson.log'});** @param {comb.logging.Appender|String} If the appender is an {@link comb.logging.appenders.Appender} then it is added.* If the appender is a string then {@link comb.logging.appenders.Appender.createAppender} will be called to create it.** @param {Object} [opts = null] If the first argument is a string then the opts will be used as constructor arguments for* creating the appender.** @return {comb.logging.Logger} for chaining.*/addAppender: function (appender, opts) {- 82
var args = argsToArray(arguments);- 82
if (isString(appender)) {- 12
this.addAppender(Appender.createAppender(appender, opts));} else {- 70
if (!isUndefinedOrNull(appender)) {- 70
var name = appender.name;- 70
if (!(name in this.__appenders)) {- 63
this.__appenders[name] = appender;- 63
if (!appender.level) {- 15
appender.level = this.level;}- 63
this._tree.addAppender(appender);}}}- 82
return this;},/*** Short cut to add a list of appenders to this Logger* @param {Array<comb.logging.Appender>} appenders** @return {comb.logging.Logger} for chaining.*/addAppenders: function (appenders) {- 14
appenders.forEach(this.addAppender.bind(this));- 14
return this;},/*** Removes and appender from this logger.* @param {String} name the name of the appender* @return {comb.logging.Logger} for chaining.*/removeAppender: function (name) {- 46
if (name in this.__appenders) {- 46
delete this.__appenders[name];- 46
this._tree.removeAppender(name);}- 46
return this;},/*** Removes a list of appenders from this logger.** @param {String[]} appenders a list of names of appenders to remove* @return {comb.logging.Logger} for chaining.*/removeAppenders: function (appenders) {- 1
appenders.forEach(this.removeAppender, this);- 1
return this;},/*** Removes all appenders from this logger and sub loggers if this Logger is additive.** @return {comb.logging.Logger} for chaining.*/removeAllAppenders: function () {- 13
Object.keys(this.__appenders).forEach(this.removeAppender.bind(this));- 13
return this;},/*** Determines if an appender is attached.** @param {String} name the name of the appender.*/isAppenderAttached: function (name) {- 38
return (name in this.__appenders);},/*** Gets an appender from this logger** @param {String} name the name of the appender.** @return {comb.logging.Appender|undefined} returns the appender with the specified name or* undefined if it is not found.*/getAppender: function (name) {- 8
var ret;- 8
if (name in this.__appenders) {- 8
ret = this.__appenders[name];}- 8
return ret;},/*** @ignore* */setters: {level: function (level) {- 46
level = Level.toLevel(level);- 46
if (this.__additive) {- 45
this.__level = level;- 45
var appenders = this.__appenders;- 45
for (var i in appenders) {- 35
appenders[i].level = level;}- 45
this._tree.level = level;} else {- 1
this.__level = level;}},additive: function (additive) {- 2
this.__additive = additive;}},/**@ignore*/getters: {/**@ignore*//**@ignore*/subLoggers: function () {- 2
return this._tree.getSubLoggers();},/**@ignore*/level: function () {- 199
return this.__level;},/**@ignore*/additive: function () {- 15
return this.__additive;},isAll: function () {- 8
return Level.ALL.isGreaterOrEqualToo(this.level);},/**@ignore*/isDebug: function () {- 8
return Level.DEBUG.isGreaterOrEqualToo(this.level);},/**@ignore*/isTrace: function () {- 8
return Level.TRACE.isGreaterOrEqualToo(this.level);},/**@ignore*/isInfo: function () {- 8
return Level.INFO.isGreaterOrEqualToo(this.level);},/**@ignore*/isWarn: function () {- 8
return Level.WARN.isGreaterOrEqualToo(this.level);},/**@ignore*/isError: function () {- 8
return Level.ERROR.isGreaterOrEqualToo(this.level);},/**@ignore*/isFatal: function () {- 8
return Level.FATAL.isGreaterOrEqualToo(this.level);},/**@ignore*/isOff: function () {- 9
return Level.OFF.equals(this.level);},/**@ignore*/name: function () {- 14
return this.__name;},/**@ignore*/tree: function () {- 13
return this._tree;},/**@ignore*/appenders: function () {- 18
var ret = [];- 18
for (var i in this.__appenders) {- 8
ret.push(this.__appenders[i]);}- 18
return ret;},categories: function () {- 2
return this._tree.categories;}}},static: {/**@lends comb.logging.Logger*//*** Return the root of all loggers*/getRootLogger: function () {- 11
return rootTree.getRootLogger();},/*** Retrieves/Creates a logger based on the name passed in** @param {String} name the name of the logger*/getLogger: function (name) {- 21
return rootTree.getLogger(name);}}}));/**** @function* @description Alias to {@link comb.logging.Logger.getLogger}. See {@link comb.logging.Logger} for more information.** @example** comb.logger("my.logger");** @memberOf comb* @namespace*/- 1
exports.logger = Logger.getLogger.bind(Logger);/*** @function* @description Shortcut to configure loggers.** @example** //same as new comb.logging.BasicConfigurator().configure();* comb.logger.configure();** //new comb.logging.PropertyConfigurator().configure("/location/to/logger/configuration.json");* comb.logger.configure("/location/to/logger/configuration.json");** @memberOf comb.logger*/- 1
exports.logger.configure = function configure() {- 4
var args = argsToArray(arguments), configurator;- 4
if (!args.length) {- 1
configurator = new configurators.BasicConfigurator();} else {- 3
var first = args[0];- 3
if (isHash(first) || isString(first)) {- 2
configurator = new configurators.PropertyConfigurator();} else {- 1
configurator = new configurators.BasicConfigurator();}}- 4
configurator.configure.apply(configurator, args);- 4
return this;};/*** @function* @description Factory method for creating appenders. See {@link comb.logging.appenders.Appender.createAppender} for* arguments.** @example** var appender = comb.logger.appender("ConsoleAppender");* comb.logger("my.logger").addAppender(appender);** @memberOf comb.logger**/- 1
exports.logger.appender = Appender.createAppender.bind(Appender);- 1
var rootLogger = new Logger("");- 1
rootTree = rootLogger._tree;/*** The root for all loggers.* @memberOf comb.logger* @type comb.logging.Logger*/- 1
exports.logger.rootLogger = rootLogger;
|
promise.js
|
Coverage99.54
SLOC844
LOC218
Missed1
|
- 1
var hitch = require("./base/functions").hitch,define = require("./define").define,base = require("./base"),argsToArray = base.argsToArray,array = base.array,forEach = array.forEach,zip = array.zip,flatten = array.flatten,isUndefinedOrNull = base.isUndefinedOrNull,isArray = base.isArray,isFunction = base.isFunction,bindIgnore = base.bindIgnore,isInstanceOf = base.isInstanceOf,nextTick = setImmediate;- 1
var Promise = define(null, {instance: {/** @lends comb.Promise.prototype */__fired: false,__results: null,__error: null,__errorCbs: null,__cbs: null,/*** Promise object used to provide seperation of success and error resolution paths for async operations.** @example* var myFunc = function(){* var promise = new Promise();* //callback the promise after 10 Secs* setTimeout(hitch(promise, "callback"), 10000);* return promise.promise();* }* var myFunc2 = function(){* var promises =[];* for(var i = 0; i < 10; i++){* promises.push(myFunc);* }* //create a new promise list with all 10 promises* return new PromiseList(promises).promise();* }** myFunc.then(function(success){}, function(error){})* //chain promise operations* myFunc.chain(myfunc).then(function(success){}, function(error){})** myFunc2.then(function(success){}, function(error){})* //chain promise operations* myFunc2.chain(myfunc).then(function(success){}, function(error){})* @constructs*/constructor: function () {- 2821
this.__errorCbs = [];- 2821
this.__cbs = [];},/*** @private*/__resolve: function () {- 2667
if (!this.__fired) {- 2667
this.__fired = true;- 2667
var cbs = this.__error ? this.__errorCbs : this.__cbs,len = cbs.length, i,results = this.__error || this.__results;- 2667
for (i = 0; i < len; i++) {- 2245
this.__callNextTick(cbs[i], results);}}},__callNextTick: function (cb, results) {- 3318
nextTick(hitch(this, function () {- 3318
cb.apply(this, results);- 3318
results = null;}));},/*** Add a callback to the callback chain of the promise*** @param {Function|comb.Promise} cb the function or promise to callback when the promise is resolved.** @return {comb.Promise} this promise for chaining*/addCallback: function (cb) {- 3339
if (cb) {- 3339
if (exports.isPromiseLike(cb)) {- 159
cb = hitch(cb, "callback");}- 3339
if (this.__fired && this.__results) {- 1059
this.__callNextTick(cb, this.__results);} else {- 2280
this.__cbs.push(cb);}}- 3339
return this;},/*** Add a callback to the errback chain of the promise** @param {Function|comb.Promise} cb the function or promise to callback when the promise errors** @return {comb.Promise} this promise for chaining*/addErrback: function (cb) {- 3221
if (cb) {- 3215
if (exports.isPromiseLike(cb)) {- 157
cb = hitch(cb, "errback");}- 3215
if (this.__fired && this.__error) {- 14
this.__callNextTick(cb, this.__error);} else {- 3201
this.__errorCbs.push(cb);}}- 3221
return this;},/**** Adds a callback or promise to be resolved for both success* and error.** @param {Function|comb.Promise} cb callback or promise to be resolved for both success* and error.* @return {comb.Promise} this promise for chaining*/both: function (cb) {- 580
this.addCallback(cb);- 580
if (exports.isPromiseLike(cb)) {- 2
this.addErrback(hitch(cb, "callback"));} else {- 578
this.addErrback(cb);}- 580
return this;},/*** When called all functions registered as callbacks are called with the passed in results.** @param {*} args variable number of results to pass back to listeners of the promise*/callback: function (args) {- 2514
args = argsToArray(arguments);- 2514
if (this.__fired) {- 1
throw new Error("Already fired!");}- 2513
this.__results = args;- 2513
this.__resolve();- 2513
return this.promise();},/*** When called all functions registered as errbacks are called with the passed in error(s)** @param {*} args number of errors to pass back to listeners of the promise*/errback: function (args) {- 155
if (this.__fired) {- 1
throw args || new Error("Already fired");}- 154
this.__error = argsToArray(arguments);- 154
this.__resolve();- 154
return this.promise();},/*** Resolved a promise using the node style callback.** @example** var promise = new Promise();* fs.readFile("file.txt", "utf8", promise.resolve.bind(promise));* promise.then(function(file){* console.log(file);* });** @param {Error} [err=null] If specified then the promise will error out* @param {...} [args] if err is null then the aruments will be used to resolve the promise.** @return {comb.Promise} for chaining.*/resolve: function (err, args) {- 4
if (err) {- 1
this.errback(err);} else {- 3
this.callback.apply(this, argsToArray(arguments, 1));}- 4
return this;},/*** Call to specify action to take after promise completes or errors** @param {Function} [callback=null] function to call after the promise completes successfully* @param {Function} [errback=null] function to call if the promise errors** @return {comb.Promise} this promise for chaining*/then: function (callback, errback) {- 1415
if (exports.isPromiseLike(callback)) {- 157
this.addCallback(callback);- 157
this.addErrback(callback);} else {- 1258
this.addCallback(callback);- 1258
this.addErrback(errback);}- 1415
return this;},/*** Call this function as a classic node callback where the first argument* will be an error, or null if no error occured. The other arugments will* be the result from the promise.** @example** promise.classic(function(err, res){* if(err){* console.log(err);* }else{* console.log(res);* }* });** @param cb callback where the first argument* will be an error, or null if no error occured. The other arugments will* be the result from the promise.* @return {comb.Promise} the promise to chain*/classic: function (cb) {- 5
if ("function" === typeof cb) {- 5
this.addErrback(function (err) {- 1
cb(err);});- 5
this.addCallback(function () {- 4
cb.apply(this, [null].concat(argsToArray(arguments)));});}- 5
return this;},/*** Call to chaining of promises** ```* new Promise()* .callback("hello")* .chain(function(previousPromiseResults){* return previousPromiseResults + " world";* }, errorHandler)* .chain(function(previousPromiseResults){* return when(dbCall());* }).classic(function(err, results){* //all promises are done* });** ```** You can also use static values** ```* new Promise().callback()* .chain("hello")* .chain(function(prev){* return prev + " world!"* }).then(function(str){* console.log(str); //"hello world!"* });* ```** If you do not provide an `errback` for each chain then it will be propogated to the final promise*** ```* new Promise()* .chain(function(){* return new comb.Promise().errback(new Error("error"));* })* .chain(function(){* return prev + " world!"* })* .classic(function(err, str){* console.log(err.message); //"error"* });* ```*** @param callback method to call this one completes. If you return a promise the execution will delay until the returned promise has resolved.* @param [errback=null] method to call if this promise errors. If errback is not specified then the returned promises* errback method will be used.** @return {comb.Promise} A new that wraps the promise for chaining*/chain: function (callback, errback) {- 582
var promise = new Promise();- 582
function errorHandler() {- 84
var args = arguments;- 84
if (errback) {- 5
nextTick(function () {- 5
try {- 5
when(isFunction(errback) ? errback.apply(this, args) : errback).then(promise);} catch (e) {- 1
promise.errback(e);}- 5
promise = args = null;});} else {- 79
promise.errback.apply(promise, args);- 79
promise = args = null;}}- 582
this.addCallback(function () {- 531
var args = arguments;- 531
nextTick(function () {- 531
try {- 531
when(isFunction(callback) ? callback.apply(this, args) : callback).then(function () {- 498
promise.callback.apply(promise, arguments);- 498
promise = args = null;}, errorHandler);} catch (e) {- 4
errorHandler(e);}});});// If no errback passed, then invoke our promise's errback to pass// on to next link in the chain.- 582
this.addErrback(errorHandler);- 582
return promise.promise();},/*** Applies the same function that returns a promise to both the callback and errback.** @param {Function} callback function to call. This function must return a Promise** @return {comb.Promise} a promise to continue chaining or to resolve with.**/chainBoth: function (callback) {- 10
var promise = new Promise();- 10
this.addCallback(function () {- 5
try {- 5
when(isFunction(callback) ? callback.apply(this, arguments) : callback).then(promise);} catch (e) {- 1
promise.errback(e);}});- 10
this.addErrback(function () {- 5
try {- 5
when(isFunction(callback) ? callback.apply(this, arguments) : callback).then(promise);} catch (e) {- 1
promise.errback(e);}});- 10
return promise.promise();},/*** Creates an object to that contains methods to listen to resolution but not the "callback" or "errback" methods.** @example** var asyncMethod = function(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, "hello"));* return ret.promise();* }** asyncMethod().callback() //throws error** @return {Object} an object containing "chain", "chainBoth", "promise", "addCallback", "addErrback", "then", "both".*/promise: function () {- 4577
var ret = {chain: this.chain.bind(this),chainBoth: this.chainBoth.bind(this),promise: function () {- 1173
return ret;}};- 4577
forEach(["addCallback", "addErrback", "then", "both", "classic"], function (action) {- 22885
ret[action] = function () {- 1830
this[action].apply(this, arguments);- 1830
return ret;}.bind(this);}, this);- 4577
return ret;}}});- 1
var PromiseList = define(Promise, {instance: {/** @lends comb.PromiseList.prototype *//*@private*/__results: null,/*@private*/__errors: null,/*@private*/__promiseLength: 0,/*@private*/__defLength: 0,/*@private*/__firedLength: 0,normalizeResults: false,/*** PromiseList object used for handling a list of Promises** @example* var myFunc = function(){* var promise = new Promise();* //callback the promise after 10 Secs* setTimeout(hitch(promise, "callback"), 10000);* return promise.promise();* }* var myFunc2 = function(){* var promises =[];* for(var i = 0; i < 10; i++){* promises.push(myFunc);* }* //create a new promise list with all 10 promises* return new PromiseList(promises).promise();* }** myFunc.then(function(success){}, function(error){})* //chain promise operations* myFunc.chain(myfunc).then(function(success){}, function(error){})** myFunc2.then(function(success){}, function(error){})* //chain promise operations* myFunc2.chain(myfunc).then(function(success){}, function(error){})** @param {comb.Promise[]} [defs=[]] the list of promises* @constructs* @augments comb.Promise* @memberOf comb* */constructor: function (defs, normalizeResults) {- 142
this.__errors = [];- 142
this.__results = [];- 142
this.normalizeResults = base.isBoolean(normalizeResults) ? normalizeResults : false;- 142
this._super(arguments);- 142
if (defs && defs.length) {- 135
this.__defLength = defs.length;- 135
forEach(defs, this.__addPromise, this);} else {- 7
this.__resolve();}},/*** Add a promise to our chain* @private* @param promise the promise to add to our chain* @param i the index of the promise in our chain*/__addPromise: function (promise, i) {- 757
promise.addCallback(hitch(this, function () {- 742
var args = argsToArray(arguments);- 742
args.unshift(i);- 742
this.callback.apply(this, args);}));- 757
promise.addErrback(hitch(this, function () {- 15
var args = argsToArray(arguments);- 15
args.unshift(i);- 15
this.errback.apply(this, args);}));},/*** Resolves the promise* @private*/__resolve: function () {- 142
if (!this.__fired) {- 142
this.__fired = true;- 142
var cbs = this.__errors.length ? this.__errorCbs : this.__cbs,len = cbs.length, i,results = this.__errors.length ? this.__errors : this.__results;- 142
for (i = 0; i < len; i++) {- 136
this.__callNextTick(cbs[i], results);}}},__callNextTick: function (cb, results) {- 145
nextTick(hitch(this, function () {- 145
cb.apply(this, [results]);}));},addCallback: function (cb) {- 145
if (cb) {- 145
if (exports.isPromiseLike(cb)) {- 1
cb = hitch(cb, "callback");}- 145
if (this.__fired && !this.__errors.length) {- 9
this.__callNextTick(cb, this.__results);} else {- 136
this.__cbs.push(cb);}}- 145
return this;},addErrback: function (cb) {- 143
if (cb) {- 143
if (exports.isPromiseLike(cb)) {- 1
cb = hitch(cb, "errback");}- 143
if (this.__fired && this.__errors.length) {- 0
this.__callNextTick(cb, this.__errors);} else {- 143
this.__errorCbs.push(cb);}}- 143
return this;},callback: function (i) {- 743
if (this.__fired) {- 1
throw new Error("Already fired!");}- 742
var args = argsToArray(arguments);- 742
if (this.normalizeResults) {- 725
args = args.slice(1);- 725
args = args.length == 1 ? args.pop() : args;}- 742
this.__results[i] = args;- 742
this.__firedLength++;- 742
if (this.__firedLength == this.__defLength) {- 130
this.__resolve();}- 742
return this.promise();},errback: function (i) {- 16
if (this.__fired) {- 1
throw new Error("Already fired!");}- 15
var args = argsToArray(arguments);- 15
if (this.normalizeResults) {- 14
args = args.slice(1);- 14
args = args.length == 1 ? args.pop() : args;}- 15
this.__errors[i] = args;- 15
this.__firedLength++;- 15
if (this.__firedLength == this.__defLength) {- 5
this.__resolve();}- 15
return this.promise();}}});/*** Creates the promise chain* @ignore* @private*/- 1
function callNext(list, results, propogate) {- 59
var ret = new Promise().callback();- 59
forEach(list, function (listItem) {- 156
ret = ret.chain(propogate ? listItem : bindIgnore(null, listItem));- 156
if (!propogate) {- 112
ret.addCallback(function (res) {- 89
results.push(res);- 89
res = null;});}});- 59
return propogate ? ret.promise() : ret.chain(results);}/*** Tests if an object is like a promise (i.e. it contains then, addCallback, addErrback)* @param obj object to test* @function* @static* @memberOf comb*/- 1
function isPromiseLike(obj) {- 11670
return !isUndefinedOrNull(obj) && (isInstanceOf(obj, Promise) || (isFunction(obj.then)&& isFunction(obj.addCallback) && isFunction(obj.addErrback)));}/*** Waits for promise and non promise values to resolve and fires callback or errback appropriately. If you pass in an array of promises* then it will wait for all promises in the list to resolve.** @example* var a = "hello";* var b = new comb.Promise().callback(world);* comb.when(a, b) => called back with ["hello", "world"];** @param {Anything...} args variable number of arguments to wait for.* @param {Function} cb the callback function* @param {Function} eb the errback function* @returns {comb.Promise} a promise that is fired when all values have resolved* @static* @memberOf comb*/- 1
function when(args, cb, eb) {- 1895
var args = argsToArray(arguments), p;- 1895
eb = base.isFunction(args[args.length - 1]) ? args.pop() : null;- 1895
cb = base.isFunction(args[args.length - 1]) ? args.pop() : null;- 1895
if (eb && !cb) {- 9
cb = eb;- 9
eb = null;}- 1895
if (!args.length) {- 7
p = new Promise().callback(args);- 1888
} else if (args.length == 1) {- 1848
args = args.pop();- 1848
if (isPromiseLike(args)) {- 848
p = args;- 1000
} else if (isArray(args) && array.every(args, isPromiseLike)) {- 91
p = new PromiseList(args, true);} else {- 909
p = new Promise().callback(args);}} else {- 40
p = new PromiseList(args.map(function (a) {- 135
return exports.isPromiseLike(a) ? a : new Promise().callback(a);}), true);}- 1895
if (cb) {- 15
p.addCallback(cb);}- 1895
if (eb) {- 6
p.addErrback(eb);}- 1895
return p.promise();}/*** Wraps traditional node style functions with a promise.* @example** var fs = require("fs");* var readFile = comb.wrap(fs.readFile, fs);* readFile(__dirname + "/test.json").then(* function(buffer){* console.log(contents);* },* funciton(err){** } console.error(err);* );*** @param {Function} fn function to wrap* @param {Object} scope scope to call the function in** @return {Funciton} a wrapped function* @static* @memberOf comb*/- 1
function wrap(fn, scope) {- 2
return function () {- 2
var ret = new Promise();- 2
var args = argsToArray(arguments);- 2
args.push(ret.resolve.bind(ret));- 2
fn.apply(scope || this, args);- 2
return ret.promise();}}/*** Executes a list of items in a serial manner. If the list contains promises then each promise* will be executed in a serial manner, if the list contains non async items then the next item in the list* is called.** @example** var asyncAction = function(item, timeout){* var ret = new comb.Promise();* setTimeout(comb.hitchIgnore(ret, "callback", item), timeout);* return ret.promise();* };** comb.serial([* comb.partial(asyncAction, 1, 1000),* comb.partial(asyncAction, 2, 900),* comb.partial(asyncAction, 3, 800),* comb.partial(asyncAction, 4, 700),* comb.partial(asyncAction, 5, 600),* comb.partial(asyncAction, 6, 500)* ]).then(function(results){* console.log(results); // [1,2,3,4,5,6];* });**** @param list* @param callback* @param errback* @static* @memberOf comb*/- 1
function serial(list, callback, errback) {- 56
if (base.isArray(list)) {- 55
return callNext(list, [], false);} else {- 1
throw new Error("When calling comb.serial the first argument must be an array");}}/*** Works just like {@link comb.Promise#chain} method, allowing you to propogate results from one funciton to another.* This is different than {@link comb.serial} in that it propogates results from one promise to the next, where* {@link comb.serial} does not.** @example** function asyncAction(add, timeout) {* return function (num) {* num = num || 0;* var ret = new comb.Promise();* setTimeout(function () {* ret.callback(num + add);* }, timeout);* return ret;* }* }** comb.chain([* asyncAction(1, 100),* asyncAction(2, 100),* asyncAction(3, 100),* asyncAction(4, 100),* asyncAction(5, 100),* ]).then(function(results){* console.log(results); //15* });** @param {function[]} list an array of function to call.* @return {comb.Promise} a promise that will resolve with the results of the last function in the list.* @static* @memberOf comb*/- 1
function chain(list) {- 5
if (base.isArray(list)) {- 4
return callNext(list, [], true);} else {- 1
throw new Error("When calling comb.serial the first argument must be an array");}}/*** Ensures that a promise is resolved before a the function can be run.** For example suppose you have to ensure that you are connected to a database before you execute a function.** ```* var findUser = comb.wait(connect(), function findUser(id){* //this wont execute until we are connected* return User.findById(id);* });** comb.when(findUser(1), findUser(2)).then(function(users){* var user1 = users[0], user2 = users[1];* });** ```** @param args variable number of arguments to wait on. See {@link comb.when}.* @param {Function} fn function that will wait.* @return {Function} a function that will wait on the args to resolve.* @memberOf comb* @static*/- 1
function wait(args, fn) {- 2
var args = argsToArray(arguments), resolved = false;- 2
fn = args.pop();- 2
var p = when(args);- 2
return function waiter() {- 3
if (!resolved) {- 2
var args = arguments;- 2
return p.chain(function () {- 2
resolved = true;- 2
p = null;- 2
return fn.apply(this, args);}.bind(this));} else {- 1
return when(fn.apply(this, arguments));}}}- 1
base.merge(exports, {isPromiseLike: isPromiseLike,when: when,wrap: wrap,wait: wait,serial: serial,chain: chain,Promise: Promise,PromiseList: PromiseList});
|
async.js
|
Coverage100.00
SLOC1235
LOC174
Missed0
|
/*** @ignoreCode* @name async* @memberOf comb* @namespace utilities for working with promises.*/- 1
var promise = require("./promise.js"),when = promise.when,serial = promise.serial,PromiseList = promise.PromiseList,base = require("./base"),merge = base.merge,isDefined = base.isDefined,isNumber = base.isNumber,isString = base.isString,argsToArray = base.argsToArray,array = base.array,isArray = base.isArray,Promise = promise.Promise,isFunction = base.isFunction,sum = array.sum,avg = array.avg,sort = array.sort,min = array.min,max = array.max,map = array.map,forEach = array.forEach,difference = array.difference,removeDuplicates = array.removeDuplicates,unique = array.unique,rotate = array.rotate,permutations = array.permutations,zip = array.zip,transpose = array.transpose,valuesAt = array.valuesAt,union = array.union,intersect = array.intersect,powerSet = array.powerSet,cartesian = array.cartesian,compact = array.compact,multiply = array.multiply,flatten = array.flatten,invoke = array.invoke,nextTick = setImmediate;- 1
function _loopResults(cb, scope, results, index, offset, limit) {- 79
return function () {- 79
return when(results.slice(offset, limit + offset).map(function (r, i) {- 574
var ret = new Promise();- 574
nextTick(function () {- 574
try {- 574
when(cb.apply(scope || results, [r, i + offset, results])).then(function () {- 564
ret.callback.apply(ret, arguments);}, function () {- 5
ret.errback.apply(ret, arguments);});} catch (e) {- 5
ret.errback(e);}});- 574
ret.both(function () {- 574
cb = scope = results = index = offset = limit = null;})- 574
return ret;}));};}- 1
function asyncLoop(promise, cb, scope, limit) {- 52
if (isNumber(scope)) {- 13
limit = scope;- 13
scope = null;}- 52
return when(promise).chain(function (results) {- 52
var loopResults = (isArray(results) ? results : [results]);- 52
limit = limit || loopResults.length;- 52
var list = [];- 52
for (var offset = 0, i = 0, l = loopResults.length; offset < l; offset += limit, i++) {- 79
list.push(_loopResults(cb, scope, loopResults, i, offset, limit));}- 52
var ret = new Promise();- 52
serial(list).then(function (loopResults) {- 42
ret.callback({loopResults: flatten(loopResults) || [], arr: results});// loopResults = null;// results = null;}, function (error) {- 10
error = compact(error);- 10
ret.errback(error.length === 1 ? error[0] : error);// loopResults = null;// results = null;});- 52
return ret;});}- 1
function normalizeResult(result) {- 92
return isArray(result) ? result : isDefined(result) ? [result] : result;}/*** Loops through the results of an promise. The promise can return an array or just a single item.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.forEach(asyncArr(), function(){* //do something with it* }).then(function(arr){* console.log(arr); //[1,2,3,4,5];* });** ```** You may also return a promise from the iterator block.** ```* var myNewArr = [];** comb.async.forEach(asyncArr(), function(item, index){* var ret = new comb.Promise();* process.nextTick(function(){* myNewArr.push([item, index]);* ret.callback();* });* return ret.promise();* }).then(function(){* console.log(myNewArr) //[[1,0], [2,1], [3,2], [4,3], [5,4]]* });* ```*** @param {comb.Promise|Array} promise the promise or array to loop through* @param {Function} iterator a function to invoke for each item* @param [scope] optional scope to execute the function in.* @return {comb.Promise} a promise that is resolved with the original array.* @static* @memberof comb.async* @name forEach*/- 1
function asyncForEach(promise, iterator, scope, limit) {- 11
return asyncArray(asyncLoop(promise, iterator, scope, limit).chain(function (results) {- 9
return results.arr;}));}/*** Loops through the results of an promise resolving with the return value of the iterator function.* The promise can return an array or just a single item.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.map(asyncArr(), function(item){* return item * 2;* }).then(function(arr){* console.log(arr); //[2,4,6,8,10];* });** ```** You may also return a promise from the iterator block.** ```* comb.async.map(asyncArr(), function(item, index){* var ret = new comb.Promise();* process.nextTick(function(){* ret.callback(item * 2);* });* return ret.promise();* }).then(function(){* console.log(myNewArr) //[2,4,6,8,10];* });* ```*** @param {comb.Promise|Array} promise the promise or array to loop through* @param {Function} iterator a function to invoke for each item* @param [scope] optional scope to execute the function in.* @return {comb.Promise} a promise that is resolved with the mapped array.* @static* @memberof comb.async* @name map*/- 1
function asyncMap(promise, iterator, scope, limit) {- 15
return asyncArray(asyncLoop(promise, iterator, scope, limit).chain(function (results) {- 13
return results.loopResults;}));}/*** Loops through the results of an promise resolving with the filtered array.* The promise can return an array or just a single item.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.filter(asyncArr(), function(item){* return item % 2;* }).then(function(arr){* console.log(arr); //[1,3,5];* });** ```** You may also return a promise from the iterator block.** ```* comb.async.filter(asyncArr(), function(item, index){* var ret = new comb.Promise();* process.nextTick(function(){* ret.callback(item % 2);* });* return ret.promise();* }).then(function(){* console.log(myNewArr) //[1,3,5];* })* ```*** @param {comb.Promise|Array} promise the promise or array to loop through* @param {Function} iterator a function to invoke for each item* @param [scope] optional scope to execute the function in.* @return {comb.Promise} a promise that is resolved with the filtered array.* @static* @memberof comb.async* @name filter*/- 1
function asyncFilter(promise, iterator, scope, limit) {- 7
return asyncArray(asyncLoop(promise, iterator, scope, limit).chain(function (results) {- 5
var loopResults = results.loopResults, resultArr = results.arr;- 5
return (isArray(resultArr) ? resultArr : [resultArr]).filter(function (res, i) {- 65
return loopResults[i];});}));}/*** Loops through the results of an promise resolving with true if every item passed, false otherwise.* The promise can return an array or just a single item.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.every(asyncArr(), function(item){* return item <= 5;* }).then(function(every){* console.log(every); //true* });** ```** You may also return a promise from the iterator block.** ```* comb.async.every(asyncArr(), function(item, index){* var ret = new comb.Promise();* process.nextTick(function(){* ret.callback(item == 1);* });* return ret.promise();* }).then(function(){* console.log(myNewArr) //false;* })* ```*** @param {comb.Promise|Array} promise the promise or array to loop through* @param {Function} iterator a function to invoke for each item* @param [scope] optional scope to execute the function in.* @return {comb.Promise} a promise that is resolved true if every item passed false otherwise.* @static* @memberof comb.async* @name every*/- 1
function asyncEvery(promise, iterator, scope, limit) {- 9
return asyncArray(asyncLoop(promise, iterator, scope, limit).chain(function (results) {- 7
return results.loopResults.every(function (res) {- 52
return !!res;});}));}/*** Loops through the results of an promise resolving with true if some items passed, false otherwise.* The promise can return an array or just a single item.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.some(asyncArr(), function(item){* return item == 1;* }).then(function(every){* console.log(every); //true* });** ```** You may also return a promise from the iterator block.** ```* comb.async.some(asyncArr(), function(item, index){* var ret = new comb.Promise();* process.nextTick(function(){* ret.callback(item > 5);* });* return ret.promise();* }).then(function(){* console.log(myNewArr) //false;* })* ```*** @param {comb.Promise|Array} promise the promise or array to loop through* @param {Function} iterator a function to invoke for each item* @param [scope] optional scope to execute the function in.* @return {comb.Promise} a promise that is resolved with true if some items passed false otherwise.* @static* @memberof comb.async* @name some*/- 1
function asyncSome(promise, iterator, scope, limit) {- 10
return asyncArray(asyncLoop(promise, iterator, scope, limit).chain(function (results) {- 8
return results.loopResults.some(function (res) {- 53
return !!res;});}));}/*** Zips results from promises into an array.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.zip(asyncArr(), asyncArr()).then(function(zipped){* console.log(zipped); //[[1,1],[2,2],[3,3], [4,4], [5,5]]* });** comb.async.array(asyncArr()).zip(asyncArr()).then(function(zipped){* console.log(zipped); //[[1,1],[2,2],[3,3], [4,4], [5,5]]* });** ```*** @return {comb.Promise} an array with all the arrays zipped together.* @static* @memberof comb.async* @name zip*/- 1
function asyncZip() {- 1
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 1
return zip.apply(array, normalizeResult(result).map(function (arg) {- 3
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.avg}.*** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).avg().then(function(avg){* console.log(avg); //3* })** comb.async.avg(asyncArr()).then(function(avg){* console.log(avg); //3* })** ```** @static* @memberof comb.async* @name avg*/- 1
function asyncAvg(avgPromise) {- 5
return when(avgPromise).chain(function (result) {- 5
return avg.call(array, normalizeResult(result));});}/*** Async version of {@link comb.array.cartesian}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2]);* return ret.promise;* }** comb.async.array(asyncArr()).cartesian([1,2,3]).then(function(avg){* console.log(avg); //[ [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ] ]* })** comb.async.cartesian(asyncArr(), [1,2,3]).then(function(avg){* console.log(avg); //[ [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ] ]* })** ```** @static* @memberof comb.async* @name cartesian*/- 1
function asyncCartesian() {- 3
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 3
return cartesian.apply(array, normalizeResult(result).map(function (arg) {- 6
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.compact}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,null,2,null,3,null,4,null,5]);* return ret.promise;* }** comb.async.array(asyncArr()).compact().then(function(compacted){* console.log(compacted); //[1,2,3,4,5]* })** comb.async.compact(asyncArr()).then(function(compacted){* console.log(compacted); //[1,2,3,4,5]* })** ```** @static* @memberof comb.async* @name compact*/- 1
function asyncCompact(arr) {- 2
return asyncArray(when(arr).chain(function (result) {- 2
return compact.call(array, normalizeResult(result));}));}/*** Async version of {@link comb.array.difference}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).difference([3,4,5]).then(function(diff){* console.log(diff); //[1,2]* })** comb.async.difference(asyncArr(), [3,4,5]).then(function(diff){* console.log(diff); //[1,2]* })** ```** @static* @memberof comb.async* @name difference*/- 1
function asyncDifference() {- 5
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 5
return difference.apply(array, normalizeResult(result).map(function (arg) {- 11
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.flatten}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [[1],[2],[3],[4],[5]]);* return ret.promise;* }** comb.async.array(asyncArr()).flatten().then(function(flat){* console.log(flat); //[1,2,3,4,5]* });** comb.async.flatten(asyncArr()).then(function(flat){* console.log(flat); //[1,2,3,4,5]* });** ```** @static* @memberof comb.async* @name flatten*/- 1
function asyncFlatten() {- 4
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 4
return flatten.apply(array, normalizeResult(result).map(function (arg) {- 12
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.intersect}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).intersect([3,4], [3]).then(function(intersection){* console.log(intersection); //[3]* });** comb.async.intersect(asyncArr(), [3,4]).then(function(intersection){* console.log(intersection); //[3,4]* });** ```** @static* @memberof comb.async* @name intersect*/- 1
function asyncIntersect() {- 5
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 5
return intersect.apply(array, normalizeResult(result).map(function (arg) {- 15
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.max}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).max().then(function(max){* console.log(max); //5* })** comb.async.max(asyncArr()).then(function(max){* console.log(max); //5* })** ```** @static* @memberof comb.async* @name max*/- 1
function asyncMax() {- 7
var args = argsToArray(arguments), last = args.pop(), cmp = null;- 7
if (isFunction(last) || isString(last)) {- 3
cmp = last;} else {- 4
args.push(last);}- 7
return when.apply(null, args).chain(function (result) {- 7
return max.call(array, normalizeResult(result), cmp);});}/*** Async version of {@link comb.array.min}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).min().then(function(min){* console.log(min) //3* });** comb.async.min(asyncArr()).then(function(min){* console.log(min) //3* });** ```** @static* @memberof comb.async* @name min*/- 1
function asyncMin() {- 7
var args = argsToArray(arguments), last = args.pop(), cmp = null;- 7
if (isFunction(last) || isString(last)) {- 3
cmp = last;} else {- 4
args.push(last);}- 7
return when.apply(null, args).chain(function (result) {- 7
return min.call(array, normalizeResult(result), cmp);});}/*** Async version of {@link comb.array.sort}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,3,2,5,4]);* return ret.promise;* }** comb.async.array(asyncArr()).sort().then(function(sorted){* console.log(sorted); //[1,2,3,4,5]* });** comb.async.sort(asyncArr()).then(function(sorted){* console.log(sorted); //[1,2,3,4,5]* });** ```** @static* @memberof comb.async* @name sort*/- 1
function asyncSort() {- 8
var args = argsToArray(arguments), last = args.pop(), cmp = null;- 8
if (isFunction(last) || isString(last)) {- 4
cmp = last;} else {- 4
args.push(last);}- 8
return asyncArray(when.apply(null, args).chain(function (result) {- 8
return sort.call(array, normalizeResult(result), cmp);}));}/*** Async version of {@link comb.array.multiply}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).multiply(2).then(function(mult){* console.log(mult); //[1,2,3,4,5,1,2,3,4,5]* });** comb.async.multiply(asyncArr(),2 ).then(function(mult){* console.log(mult); //[1,2,3,4,5,1,2,3,4,5]* });** ```** @static* @memberof comb.async* @name multiply*/- 1
function asyncMultiply() {- 4
var args = argsToArray(arguments), last = args.pop(), times = null;- 4
if (isNumber(last)) {- 3
times = last;} else {- 1
args.push(last);}- 4
return asyncArray(when.apply(null, args).chain(function (result) {- 4
return multiply.call(array, normalizeResult(result), times);}));}/*** Async version of {@link comb.array.permutations}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3]);* return ret.promise;* }** comb.async.array(asyncArr()).permutations().then(function(permutations){* console.log(permutations) //[ [ 1, 2, 3 ],* // [ 1, 3, 2 ],* // [ 2, 3, 1 ],* // [ 2, 1, 3 ],* // [ 3, 1, 2 ],* // [ 3, 2, 1 ] ]* });** comb.async.permutations(asyncArr()).then(function(permutations){* console.log(permutations) //[ [ 1, 2, 3 ],* // [ 1, 3, 2 ],* // [ 2, 3, 1 ],* // [ 2, 1, 3 ],* // [ 3, 1, 2 ],* // [ 3, 2, 1 ] ]* });** ```** @static* @memberof comb.async* @name permutations*/- 1
function asyncPermutations() {- 5
var args = argsToArray(arguments), last = args.pop(), times = null;- 5
if (isNumber(last)) {- 4
times = last;} else {- 1
args.push(last);}- 5
return asyncArray(when.apply(null, args).chain(function (result) {- 5
return permutations.call(array, normalizeResult(result), times);}));}/*** Async version of {@link comb.array.powerSet}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).powerSet().then(function(set){* console.log(set); //[ [], [ 1 ], [ 2 ], [ 1, 2 ], [ 3 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2, 3 ] ]* });** comb.async.powerSet(asyncArr()).then(function(set){* console.log(set); //[ [], [ 1 ], [ 2 ], [ 1, 2 ], [ 3 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2, 3 ] ]* });** ```** @static* @memberof comb.async* @name powerSet*/- 1
function asyncPowerSet(arr) {- 3
return asyncArray(when(arr).chain(function (result) {- 3
return powerSet.call(array, normalizeResult(result));}));}/*** Async version of {@link comb.array.removeDuplicates}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,2,3,3,3,4,4,4]);* return ret.promise;* }** comb.async.array(asyncArr()).removeDuplicates().then(function(unique){* console.log(unique); // [1, 2, 3, 4]* });** comb.async.removeDuplicates(asyncArray()).then(function(unique){* console.log(unique); // [1, 2, 3, 4]* });* ```** @static* @memberof comb.async* @name removeDuplicates*/- 1
function asyncRemoveDuplicates(arr) {- 4
return asyncArray(when(arr).chain(function (result) {- 4
return removeDuplicates.call(array, normalizeResult(result));}));}/*** Async version of {@link comb.array.rotate}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).rotate(2).then(function(rotated){* console.log(rotated); // [ 3, 4, 5, 1, 2 ]* });** comb.async.rotate(asyncArr(), 2).then(function(rotated){* console.log(rotated); // [ 3, 4, 5, 1, 2 ]* });** ```** @static* @memberof comb.async* @name rotate*/- 1
function asyncRotate() {- 8
var args = argsToArray(arguments), last = args.pop(), times = null;- 8
if (isNumber(last)) {- 7
times = last;} else {- 1
args.push(last);}- 8
return asyncArray(when.apply(null, args).chain(function (result) {- 8
return rotate.call(array, normalizeResult(result), times);}));}/*** Async version of {@link comb.array.sum}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).sum().then(function(sum){* console.log(sum) //15* })** comb.async.sum(asyncArr()).then(function(sum){* console.log(sum) //15* })** ```** @static* @memberof comb.async* @name sum*/- 1
function asyncSum(arr) {- 6
return when(arr).chain(function (result) {- 6
return sum.call(array, normalizeResult(result));});}/*** Async version of {@link comb.array.transpose}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [[1, 2, 3], [4, 5, 6]]);* return ret.promise;* }** comb.async.array(asyncArr()).transpose().then(function(transposed){* console.log(transposed); //[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]* });** comb.async.transpose(asyncArr()).then(function(transposed){* console.log(transposed); //[ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]* });** ```** @static* @memberof comb.async* @name transpose*/- 1
function asyncTranspose(arr) {- 3
return asyncArray(when(arr).chain(function (result) {- 3
return transpose.call(array, normalizeResult(result));}));}/*** Async version of {@link comb.array.union}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).union([3],[7], [9,10]).then(function(union){* console.log(union); //[1,2,3,4,5,7,9,10]* });** comb.async.union(asyncArr(), [3],[7], [9,10]).then(function(union){* console.log(union); //[1,2,3,4,5,7,9,10]* });** ```** @static* @memberof comb.async* @name union*/- 1
function asyncUnion() {- 2
return asyncArray(when.apply(null, argsToArray(arguments)).chain(function (result) {- 2
return union.apply(array, (normalizeResult(result)).map(function (arg) {- 7
return isArray(arg) ? arg : [arg];}));}));}/*** Async version of {@link comb.array.unique}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,2,3,3,4,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).unique().then(function(unique){* console.log(unique); //[1,2,3,4,5]* });** comb.async.unique(asyncArr()).then(function(unique){* console.log(unique); //[1,2,3,4,5]* });** ```** @static* @memberof comb.async* @name unique*/- 1
function asyncUnique() {- 2
return asyncRemoveDuplicates.apply(null, arguments);}/*** Async version of {@link comb.array.valuesAt}.** ```* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** comb.async.array(asyncArr()).valuesAt(2,3,4).then(function(values){* console.log(values); //[3,4,5]* });** comb.async.valuesAt(asyncArr(), 2,3,4).then(function(values){* console.log(values); //[3,4,5]* });** ```** @static* @memberof comb.async* @name valuesAt*/- 1
function asyncValuesAt(arrPromise) {- 3
var args = argsToArray(arguments, 1);- 3
return asyncArray(when(arrPromise).chain(function (result) {- 3
return when(valuesAt.apply(array, [normalizeResult(result)].concat(args)));}));}/*** Async version of {@link comb.array.pluck}.** ```* var when = comb.when,* array = comb.async.array;* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [* {name:{first:when("Fred"), last:"Jones"}, age:when(50), roles:["a", "b", "c"]},* {name:{first:"Bob", last:"Yukon"}, age:40, roles:when(["b", "c"])},* {name:{first:"Alice", last:"Palace"}, age:when(35), roles:["c"]},* {name:{first:when("Johnny"), last:"P."}, age:56, roles:when([])}* ]);* return ret.promise;* }** array(asyncArr()).pluck("name.first").then(function(values){* console.log(values); //["Fred", "Bob", "Alice", "Johnny"]* });** pluck(asyncArr(), "age").then(function(values){* console.log(values); //[50, 40, 35, 56]* });** ```** @static* @memberof comb.async* @name pluck*/- 1
function asyncPluck(arrPromise, property) {- 5
var args = argsToArray(arguments, 1);- 5
return asyncArray(when(arrPromise).chain(function (result) {- 5
var prop = property.split(".");- 5
result = normalizeResult(result);- 5
return asyncArray(prop).forEach(function (prop) {- 8
var exec = prop.match(/(\w+)\(\)$/);- 8
return asyncArray(result).map(function (item) {- 32
return exec ? item[exec[1]]() : item[prop];}, 1).chain(function (res) {- 8
result = res;});}, 1).chain(function () {- 5
return result;});}));}/**** Async version of {@link comb.array.invoke}.** ```* function person(name, age) {* return {* getName:function () {* return when(name);* },* getOlder:function () {* age++;* return when(this);* },* getAge:function () {* return when(age);* }* };* }** var arr = [when(person("Bob", 40)), when(person("Alice", 35)), when(person("Fred", 50)), when(person("Johnny", 56))];* console.log(comb.async.invoke(arr, "getName")); //["Bob", "Alice", "Fred", "Johnny"]* console.log(array(arr).invoke("getOlder").pluck("getAge")) //[41, 36, 51, 57]* ```* @static* @memberOf comb.async* @name invoke*/- 1
function asyncInvoke(arrPromise) {- 2
var args = argsToArray(arguments, 1);- 2
return asyncArray(when(arrPromise).chain(function (result) {- 2
return when(invoke.apply(array, [normalizeResult(result)].concat(args)));}));}- 1
var asyncExports = (exports.async = {array: asyncArray,forEach: asyncForEach,map: asyncMap,filter: asyncFilter,every: asyncEvery,some: asyncSome,zip: asyncZip,sum: asyncSum,avg: asyncAvg,sort: asyncSort,min: asyncMin,max: asyncMax,difference: asyncDifference,removeDuplicates: asyncRemoveDuplicates,unique: asyncUnique,rotate: asyncRotate,permutations: asyncPermutations,transpose: asyncTranspose,valuesAt: asyncValuesAt,union: asyncUnion,intersect: asyncIntersect,powerSet: asyncPowerSet,cartesian: asyncCartesian,compact: asyncCompact,multiply: asyncMultiply,flatten: asyncFlatten,pluck: asyncPluck,invoke: asyncInvoke});- 1
var methods = ["forEach", "map", "filter", "some", "every", "zip", "sum", "avg", "sort", "min", "max", "difference", "removeDuplicates", "unique", "rotate","permutations", "transpose", "valuesAt", "union", "intersect", "powerSet", "cartesian", "compact","multiply", "flatten", "pluck", "invoke"];/*** Exposes array methods on a {@link comb.Promise}.** The methods added are.** * forEach : See {@link comb.async.forEach}.* * map : See {@link comb.async.map}.* * filter : See {@link comb.async.filter}.* * some : See {@link comb.async.some}.* * every : See {@link comb.async.every}.* * zip : See {@link comb.async.zip}.* * sum : See {@link comb.async.sum}.* * avg : See {@link comb.async.avg}.* * sort : See {@link comb.async.sort}.* * min : See {@link comb.async.min}.* * max : See {@link comb.async.max}.* * difference : See {@link comb.async.difference}.* * removeDuplicates : See {@link comb.async.removeDuplicates}.* * unique : See {@link comb.async.unique}.* * rotate : See {@link comb.async.rotate}.* * permutations : See {@link comb.async.permutations}.* * transpose : See {@link comb.async.transpose}.* * valuesAt : See {@link comb.async.valuesAt}.* * union : See {@link comb.async.union}.* * intersect : See {@link comb.async.intersect}.* * powerSet : See {@link comb.async.powerSet}.* * cartesian : See {@link comb.async.cartesian}.* * compact : See {@link comb.async.compact}.* * multiply : See {@link comb.async.multiply}.* * flatten : See {@link comb.async.flatten}.* * pluck : See {@link comb.async.pluck}.* * invoke : See {@link comb.async.invoke}.** When using this method each of the methods are chainable so you can combine actions.** ```* var array = comb.async.array;* function asyncArr(){* var ret = new comb.Promise();* process.nextTick(ret.callback.bind(ret, [1,2,3,4,5]);* return ret.promise;* }** array(asyncArr())* .map(function (num, i) {* return num * (i + 1);* }).filter(function (num) {* return num % 2;* }).avg().then(function(avg){* console.log(avg); //11.666666666666666* });* ```* @param {comb.Promise|[]} p the promise or array to use.** @static* @memberof comb.async* @name array*/- 1
function asyncArray(p) {- 626
var ret;- 626
if (!p || !p.__isArrayAsync__) {- 410
ret = merge(when(p), {promise: function () {- 216
return asyncArray(this)}});- 410
forEach(methods, function (m) {- 11070
var func = asyncExports[m];- 11070
ret[m] = function () {- 143
var args = argsToArray(arguments), mRet = new Promise();- 143
nextTick(function () {- 143
func.apply(null, [ret].concat(args)).then(mRet);});- 143
return asyncArray(mRet);};});- 410
ret.__isArrayAsync__ = true;} else {- 216
ret = p;}- 626
p = null;- 626
return ret;}
|
base/array.js
|
Coverage100.00
SLOC1089
LOC357
Missed0
|
- 1
var obj = require("./object"),merge = obj.merge,misc = require("./misc"),argsToArray = misc.argsToArray,string = require("./string"),isString = string.isString,number = require("./number.js"),floor = Math.floor,abs = Math.abs,mathMax = Math.max,mathMin = Math.min;- 1
var isArray = exports.isArray = function isArray(obj) {- 17163
return Object.prototype.toString.call(obj) === "[object Array]";};- 1
function isDate(obj) {- 126
var undef;- 126
return (obj !== undef && typeof obj === "object" && obj instanceof Date);}- 1
function cross(num, cros) {- 21
var ret = reduceRight(cros, function (a, b) {- 57
if (!isArray(b)) {- 57
b = [b];}- 57
b.unshift(num);- 57
a.unshift(b);- 57
return a;}, []);- 21
return ret;}- 1
function permute(num, cross, length) {- 18
var ret = [];- 18
for (var i = 0; i < cross.length; i++) {- 36
ret.push([num].concat(rotate(cross, i)).slice(0, length));}- 18
return ret;}- 1
function intersection(a, b) {- 30
var ret = [], aOne;- 30
if (isArray(a) && isArray(b) && a.length && b.length) {- 30
for (var i = 0, l = a.length; i < l; i++) {- 105
aOne = a[i];- 105
if (indexOf(b, aOne) !== -1) {- 84
ret.push(aOne);}}}- 30
return ret;}- 1
var _sort = (function () {- 1
var isAll = function (arr, test) {- 63
return every(arr, test);};- 1
var defaultCmp = function (a, b) {- 90
return a - b;};- 1
var dateSort = function (a, b) {- 27
return a.getTime() - b.getTime();};- 1
return function _sort(arr, property) {- 66
var ret = [];- 66
if (isArray(arr)) {- 66
ret = arr.slice();- 66
if (property) {- 30
if (typeof property === "function") {- 3
ret.sort(property);} else {- 27
ret.sort(function (a, b) {- 81
var aProp = a[property], bProp = b[property];- 81
if (isString(aProp) && isString(bProp)) {- 27
return aProp > bProp ? 1 : aProp < bProp ? -1 : 0;- 54
} else if (isDate(aProp) && isDate(bProp)) {- 27
return aProp.getTime() - bProp.getTime()} else {- 27
return aProp - bProp;}});}} else {- 36
if (isAll(ret, isString)) {- 9
ret.sort();- 27
} else if (isAll(ret, isDate)) {- 9
ret.sort(dateSort);} else {- 18
ret.sort(defaultCmp);}}}- 66
return ret;};})();- 1
function indexOf(arr, searchElement, fromIndex) {- 299
if (!isArray(arr)) {- 1
throw new TypeError();}- 298
var t = Object(arr);- 298
var len = t.length >>> 0;- 298
if (len === 0) {- 33
return -1;}- 265
var n = 0;- 265
if (arguments.length > 2) {- 8
n = Number(arguments[2]);- 8
if (n !== n) { // shortcut for verifying if it's NaN- 2
n = 0;- 6
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {- 2
n = (n > 0 || -1) * floor(abs(n));}}- 265
if (n >= len) {- 2
return -1;}- 263
var k = n >= 0 ? n : mathMax(len - abs(n), 0);- 263
for (; k < len; k++) {- 568
if (k in t && t[k] === searchElement) {- 158
return k;}}- 105
return -1;}- 1
function lastIndexOf(arr, searchElement, fromIndex) {- 12
if (!isArray(arr)) {- 1
throw new TypeError();}- 11
var t = Object(arr);- 11
var len = t.length >>> 0;- 11
if (len === 0) {- 1
return -1;}- 10
var n = len;- 10
if (arguments.length > 2) {- 8
n = Number(arguments[2]);- 8
if (n !== n) {- 2
n = 0;- 6
} else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {- 2
n = (n > 0 || -1) * floor(abs(n));}}- 10
var k = n >= 0 ? mathMin(n, len - 1) : len - abs(n);- 10
for (; k >= 0; k--) {- 18
if (k in t && t[k] === searchElement) {- 6
return k;}}- 4
return -1;}- 1
function filter(arr, iterator, scope) {- 37
if (!isArray(arr) || typeof iterator !== "function") {- 1
throw new TypeError();}- 36
var t = Object(arr);- 36
var len = t.length >>> 0;- 36
var res = [];- 36
for (var i = 0; i < len; i++) {- 138
if (i in t) {- 98
var val = t[i]; // in case fun mutates this- 98
if (iterator.call(scope, val, i, t)) {- 58
res.push(val);}}}- 36
return res;}- 1
function forEach(arr, iterator, scope) {- 12959
if (!isArray(arr) || typeof iterator !== "function") {- 1
throw new TypeError();}- 12958
for (var i = 0, len = arr.length; i < len; ++i) {- 91526
iterator.call(scope || arr, arr[i], i, arr);}- 12958
return arr;}- 1
function every(arr, iterator, scope) {- 412
if (!isArray(arr) || typeof iterator !== "function") {- 1
throw new TypeError();}- 411
var t = Object(arr);- 411
var len = t.length >>> 0;- 411
for (var i = 0; i < len; i++) {- 959
if (i in t && !iterator.call(scope, t[i], i, t)) {- 300
return false;}}- 111
return true;}- 1
function some(arr, iterator, scope) {- 7
if (!isArray(arr) || typeof iterator !== "function") {- 1
throw new TypeError();}- 6
var t = Object(arr);- 6
var len = t.length >>> 0;- 6
for (var i = 0; i < len; i++) {- 30
if (i in t && iterator.call(scope, t[i], i, t)) {- 2
return true;}}- 4
return false;}- 1
function map(arr, iterator, scope) {- 53
if (!isArray(arr) || typeof iterator !== "function") {- 1
throw new TypeError();}- 52
var t = Object(arr);- 52
var len = t.length >>> 0;- 52
var res = [];- 52
for (var i = 0; i < len; i++) {- 177
if (i in t) {- 177
res.push(iterator.call(scope, t[i], i, t));}}- 52
return res;}- 1
function reduce(arr, accumulator, curr) {- 181
if (!isArray(arr) || typeof accumulator !== "function") {- 1
throw new TypeError();}- 180
var i = 0, l = arr.length >> 0;- 180
if (arguments.length < 3) {- 24
if (l === 0) {- 1
throw new TypeError("Array length is 0 and no second argument");}- 23
curr = arr[0];- 23
i = 1; // start accumulating at the second element} else {- 156
curr = arguments[2];}- 179
while (i < l) {- 478
if (i in arr) {- 478
curr = accumulator.call(undefined, curr, arr[i], i, arr);}- 478
++i;}- 179
return curr;}- 1
function reduceRight(arr, accumulator, curr) {- 27
if (!isArray(arr) || typeof accumulator !== "function") {- 1
throw new TypeError();}- 26
var t = Object(arr);- 26
var len = t.length >>> 0;// no value to return if no initial value, empty array- 26
if (len === 0 && arguments.length === 2) {- 1
throw new TypeError();}- 25
var k = len - 1;- 25
if (arguments.length >= 3) {- 23
curr = arguments[2];} else {- 2
do {- 2
if (k in arr) {- 2
curr = arr[k--];- 2
break;}}while (true);}- 25
while (k >= 0) {- 75
if (k in t) {- 75
curr = accumulator.call(undefined, curr, t[k], k, t);}- 75
k--;}- 25
return curr;}/*** converts anything to an array** @example* comb.array.toArray({a : "b", b : "c"}) => [["a","b"], ["b","c"]];* comb.array.toArray("a") => ["a"]* comb.array.toArray(["a"]) => ["a"];* comb.array.toArray() => [];* comb.array.toArray("a", {a : "b"}) => ["a", ["a", "b"]];** @static* @memberOf comb.array*/- 1
function toArray(o) {- 91
var ret = [];- 91
if (o != null) {- 90
var args = argsToArray(arguments);- 90
if (args.length === 1) {- 88
if (isArray(o)) {- 75
ret = o;- 13
} else if (obj.isHash(o)) {- 4
for (var i in o) {- 6
if (o.hasOwnProperty(i)) {- 6
ret.push([i, o[i]]);}}} else {- 9
ret.push(o);}} else {- 2
forEach(args, function (a) {- 4
ret = ret.concat(toArray(a));});}}- 91
return ret;}/*** Sums all items in an array** @example** comb.array.sum([1,2,3]) => 6* comb.array.sum(["A","B","C"]) => "ABC";* var d1 = new Date(1999), d2 = new Date(2000), d3 = new Date(3000);* comb.array.sum([d1,d2,d3]) => "Wed Dec 31 1969 18:00:01 GMT-0600 (CST)"* + "Wed Dec 31 1969" 18:00:02 GMT-0600 (CST)"* + "Wed Dec 31 1969 18:00:03 GMT-0600 (CST)"* comb.array.sum([{},{},{}]) => "[object Object][object Object][object Object]";** @param {Number[]} array the array of numbers to sum* @static* @memberOf comb.array*/- 1
function sum(array) {- 27
array = array || [];- 27
if (array.length) {- 21
return reduce(array, function (a, b) {- 49
return a + b;});} else {- 6
return 0;}}/*** Averages an array of numbers.* @example** comb.array.avg([1,2,3]); //2** @param {Number[]} array - an array of numbers* @return {Number} the average of all the numbers in the array.* @throws {Error} if the array is not all numbers.* @static* @memberOf comb.array*/- 1
function avg(arr) {- 13
arr = arr || [];- 13
if (arr.length) {- 8
var total = sum(arr);- 8
if (number.isNumber(total)) {- 4
return total / arr.length;} else {- 4
throw new Error("Cannot average an array of non numbers.");}} else {- 5
return 0;}}/*** Allows the sorting of an array based on a property name instead. This can also* act as a sort that does not change the original array.** <b>NOTE:</b> this does not change the original array!** @example* comb.array.sort([{a : 1}, {a : 2}, {a : -2}], "a"); //[{a : -2}, {a : 1}, {a : 2}];* @param {Array} arr the array to sort* @param {String|Function} cmp the property to sort on. Or a function used to compare.* @return {Array} a copy of the original array that is sorted.** @static* @memberOf comb.array*/- 1
function sort(arr, cmp) {- 24
return _sort(arr, cmp);}/*** Finds that min value of an array. If a second argument is provided and it is a function* it will be used as a comparator function. If the second argument is a string then it will be used* as a property look up on each item.** @example* comb.array.min([{a : 1}, {a : 2}, {a : -2}], "a"); //{a : -2}* comb.array.min([{a : 1}, {a : 2}, {a : -2}], function(a,b){* return a.a - b.a* }); //{a : -2}** @param {Array} arr the array to find the min value on* @param {String|Function} cmp the property to sort on. Or a function used to compare.* @return {*}** @static* @memberOf comb.array*/- 1
function min(arr, cmp) {- 21
return _sort(arr, cmp)[0];}/*** Finds that max value of an array. If a second argument is provided and it is a function* it will be used as a comparator function. If the second argument is a string then it will be used* as a property look up on each item.** @example* comb.array.max([{a : 1}, {a : 2}, {a : -2}], "a"); //{a : 2}* comb.array.max([{a : 1}, {a : 2}, {a : -2}], function(a,b){* return a.a - b.a* }); //{a : 2}** @param arr the array to find the max value on* @param {String|Function} cmp the property to sort on. Or a function used to compare.* @return {*} the maximum value of the array based on the provided cmp.** @static* @memberOf comb.array*/- 1
function max(arr, cmp) {- 21
return _sort(arr, cmp)[arr.length - 1];}/*** Finds the difference of the two arrays.** @example** comb.array.difference([1,2,3], [2,3]); //[1]* comb.array.difference(["a","b",3], [3]); //["a","b"]** @param {Array} arr1 the array we are subtracting from* @param {Array} arr2 the array we are subtracting from arr1* @return {*} the difference of the arrays.** @static* @memberOf comb.array*/- 1
function difference(arr1, arr2) {- 15
var ret = arr1, args = flatten(argsToArray(arguments, 1));- 15
if (isArray(arr1)) {- 15
ret = filter(arr1, function (a) {- 42
return indexOf(args, a) === -1;});}- 15
return ret;}/*** Removes duplicates from an array** @example** comb.array.removeDuplicates([1,1,1]) => [1]* comb.array.removeDuplicates([1,2,3,2]) => [1,2,3]** @param {Aray} array the array of elements to remove duplicates from** @static* @memberOf comb.array*/- 1
function removeDuplicates(arr) {- 33
if (isArray(arr)) {- 33
return reduce(arr, function (a, b) {- 141
if (indexOf(a, b) === -1) {- 96
return a.concat(b);} else {- 45
return a;}}, []);}}/**** See {@link comb.array.removeDuplicates}** @static* @memberOf comb.array*/- 1
function unique(arr) {- 4
return removeDuplicates(arr);}/*** Rotates an array the number of specified positions** @example* var arr = ["a", "b", "c", "d"];* comb.array.rotate(arr) => ["b", "c", "d", "a"]* comb.array.rotate(arr, 2) => ["c", "d", "a", "b"]);* comb.array.rotate(arr, 3) => ["d", "a", "b", "c"]);* comb.array.rotate(arr, 4) => ["a", "b", "c", "d"]);* comb.array.rotate(arr, -1) => ["d", "a", "b", "c"]);* comb.array.rotate(arr, -2) => ["c", "d", "a", "b"]);* comb.array.rotate(arr, -3) => ["b", "c", "d", "a"]);* comb.array.rotate(arr, -4) => ["a", "b", "c", "d"]);** @param {Array} array the array of elements to remove duplicates from* @param {Number} numberOfTimes the number of times to rotate the array** @static* @memberOf comb.array*/- 1
function rotate(arr, numberOfTimes) {- 174
var ret = arr.slice();- 174
if (typeof numberOfTimes !== "number") {- 3
numberOfTimes = 1;}- 174
if (numberOfTimes && isArray(arr)) {- 96
if (numberOfTimes > 0) {- 66
ret.push(ret.shift());- 66
numberOfTimes--;} else {- 30
ret.unshift(ret.pop());- 30
numberOfTimes++;}- 96
return rotate(ret, numberOfTimes);} else {- 78
return ret;}}/*** Finds all permutations of an array** @example* var arr = [1,2,3];* comb.array.permutations(arr) => [[ 1, 2, 3 ],[ 1, 3, 2 ],[ 2, 3, 1 ],* [ 2, 1, 3 ],[ 3, 1, 2 ],[ 3, 2, 1 ]]* comb.array.permutations(arr, 2) => [[ 1, 2],[ 1, 3],[ 2, 3],[ 2, 1],[ 3, 1],[ 3, 2]]* comb.array.permutations(arr, 1) => [[1],[2],[3]]* comb.array.permutations(arr, 0) => [[]]* comb.array.permutations(arr, 4) => []** @param {Array} arr the array to permute.* @param {Number} length the number of elements to permute.* @static* @memberOf comb.array*/- 1
function permutations(arr, length) {- 15
var ret = [];- 15
if (isArray(arr)) {- 15
var copy = arr.slice(0);- 15
if (typeof length !== "number") {- 3
length = arr.length;}- 15
if (!length) {- 3
ret = [[]];- 12
} else if (length <= arr.length) {- 9
ret = reduce(arr, function (a, b, i) {- 27
var ret;- 27
if (length > 1) {- 18
ret = permute(b, rotate(copy, i).slice(1), length);} else {- 9
ret = [[b]];}- 27
return a.concat(ret);}, []);}}- 15
return ret;}/*** Zips to arrays together** @example* var a = [ 4, 5, 6 ], b = [ 7, 8, 9 ]* comb.array.zip([1], [2], [3]) => [[ 1, 2, 3 ]]);* comb.array.zip([1,2], [2], [3]) => [[ 1, 2, 3 ],[2, null, null]]* comb.array.zip([1,2,3], a, b) => [[1, 4, 7],[2, 5, 8],[3, 6, 9]]* comb.array.zip([1,2], a, b) => [[1, 4, 7],[2, 5, 8]]* comb.array.zip(a, [1,2], [8]) => [[4,1,8],[5,2,null],[6,null,null]]** @param arrays variable number of arrays to zip together** @static* @memberOf comb.array*/- 1
function zip() {- 11
var ret = [];- 11
var arrs = argsToArray(arguments);- 11
if (arrs.length > 1) {- 11
var arr1 = arrs.shift();- 11
if (isArray(arr1)) {- 11
ret = reduce(arr1, function (a, b, i) {- 38
var curr = [b];- 38
for (var j = 0; j < arrs.length; j++) {- 76
var currArr = arrs[j];- 76
if (isArray(currArr) && !misc.isUndefined(currArr[i])) {- 66
curr.push(currArr[i]);} else {- 10
curr.push(null);}}- 38
a.push(curr);- 38
return a;}, []);}}- 11
return ret;}/*** Transposes an array of arrays* @example** comb.array.transpose([[1,2,3], [4,5,6]]) => [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]* comb.array.transpose([[1,2], [3,4], [5,6]]) => [ [ 1, 3, 5 ], [ 2, 4, 6 ] ]* comb.array.transpose([[1], [3,4], [5,6]]) => [[1]])** @param [Array[Array[]]] arr Array of arrays** @static* @memberOf comb.array*/- 1
function transpose(arr) {- 9
var ret = [];- 9
if (isArray(arr) && arr.length) {- 9
var last;- 9
forEach(arr, function (a) {- 24
if (isArray(a) && (!last || a.length === last.length)) {- 18
forEach(a, function (b, i) {- 39
if (!ret[i]) {- 18
ret[i] = [];}- 39
ret[i].push(b);});- 18
last = a;}});}- 9
return ret;}/*** Retrieves values at specified indexes in the array** @example** var arr =["a", "b", "c", "d"]* comb.array.valuesAt(arr, 1,2,3) => ["b", "c", "d"];* comb.array.valuesAt(arr, 1,2,3, 4) => ["b", "c", "d", null];* comb.array.valuesAt(arr, 0,3) => ["a", "d"];** @param {Array} arr the array to retrieve values from* @param {Number} indexes variable number of indexes to retrieve** @static* @memberOf comb.array*/- 1
function valuesAt(arr, indexes) {- 9
var ret = [];- 9
indexes = argsToArray(arguments);- 9
arr = indexes.shift();- 9
var l = arr.length;- 9
if (isArray(arr) && indexes.length) {- 9
for (var i = 0; i < indexes.length; i++) {- 27
ret.push(arr[indexes[i]] || null);}}- 9
return ret;}/*** Union a variable number of arrays together** @example** comb.array.union(['a','b','c'], ['b','c', 'd']) => ["a", "b", "c", "d"]* comb.array.union(["a"], ["b"], ["c"], ["d"], ["c"]) => ["a", "b", "c", "d"]** @param arrs variable number of arrays to union** @static* @memberOf comb.array*/- 1
function union() {- 6
var ret = [];- 6
var arrs = argsToArray(arguments);- 6
if (arrs.length > 1) {- 6
ret = removeDuplicates(reduce(arrs, function (a, b) {- 21
return a.concat(b);}, []));}- 6
return ret;}/*** Finds the intersection of arrays* NOTE : this function accepts an arbitrary number of arrays** @example* comb.array.intersect([1,2], [2,3], [2,3,5]) => [2]* comb.array.intersect([1,2,3], [2,3,4,5], [2,3,5]) => [2,3]* comb.array.intersect([1,2,3,4], [2,3,4,5], [2,3,4,5]) => [2,3,4]* comb.array.intersect([1,2,3,4,5], [1,2,3,4,5], [1,2,3]) => [1,2,3]* comb.array.intersect([[1,2,3,4,5],[1,2,3,4,5],[1,2,3]]) => [1,2,3]** @param {Array} a* @param {Array} b** @static* @memberOf comb.array*/- 1
function intersect(a, b) {- 15
var collect = [], set;- 15
var args = argsToArray(arguments);- 15
if (args.length > 1) {//assume we are intersections all the lists in the array- 13
set = args;} else {- 2
set = args[0];}- 15
if (isArray(set)) {- 15
var x = set.shift();- 15
collect = reduce(set, function (a, b) {- 30
return intersection(a, b);}, x);}- 15
return removeDuplicates(collect);}/*** Finds the powerset of an array** @example** comb.array.powerSet([1,2]) => [* [],* [ 1 ],* [ 2 ],* [ 1, 2 ]* ]* comb.array.powerSet([1,2,3]) => [* [],* [ 1 ],* [ 2 ],* [ 1, 2 ],* [ 3 ],* [ 1, 3 ],* [ 2, 3 ],* [ 1, 2, 3 ]* ]* comb.array.powerSet([1,2,3,4]) => [* [],* [ 1 ],* [ 2 ],* [ 1, 2 ],* [ 3 ],* [ 1, 3 ],* [ 2, 3 ],* [ 1, 2, 3 ],* [ 4 ],* [ 1, 4 ],* [ 2, 4 ],* [ 1, 2, 4 ],* [ 3, 4 ],* [ 1, 3, 4 ],* [ 2, 3, 4 ],* [ 1, 2, 3, 4 ]* ]** @param {Array} arr the array to find the powerset of** @static* @memberOf comb.array*/- 1
function powerSet(arr) {- 9
var ret = [];- 9
if (isArray(arr) && arr.length) {- 9
ret = reduce(arr, function (a, b) {- 27
var ret = map(a, function (c) {- 75
return c.concat(b);});- 27
return a.concat(ret);}, [[]]);}- 9
return ret;}/*** Find the cartesian product of two arrays** @example** comb.array.cartesian([1,2], [2,3]) => [* [1,2],* [1,3],* [2,2],* [2,3]* ]* comb.array.cartesian([1,2], [2,3,4]) => [* [1,2],* [1,3],* [1,4] ,* [2,2],* [2,3],* [2,4]* ]* comb.array.cartesian([1,2,3], [2,3,4]) => [* [1,2],* [1,3],* [1,4] ,* [2,2],* [2,3],* [2,4] ,* [3,2],* [3,3],* [3,4]* ]** @param {Array} a* @param {Array} b** @static* @memberOf comb.array*/- 1
function cartesian(a, b) {- 30
var ret = [];- 30
if (isArray(a) && isArray(b) && a.length && b.length) {- 21
ret = cross(a[0], b).concat(cartesian(a.slice(1), b));}- 30
return ret;}/*** Compacts an array removing null or undefined objects from the array.** @example** var x;* comb.array.compact([1,null,null,x,2]) => [1,2]* comb.array.compact([1,2]) => [1,2]** @param {Array} arr* @static* @memberOf comb.array*/- 1
function compact(arr) {- 16
var ret = [];- 16
if (isArray(arr) && arr.length) {- 16
ret = filter(arr, function (item) {- 31
return !misc.isUndefinedOrNull(item);});}- 16
return ret;}/*** Creates a new array that is the result of the array concated the number of* times. If times is not specified or it equals 0 then it defaults to 1.* @param {Array} arr the array to multiply.* @param {Number} [times=1] the number of times to multiple the array.* @return {Array} a new array that is the result of the array multiplied the number of times specified.** @static* @memberOf comb.array*/- 1
function multiply(arr, times) {- 12
times = number.isNumber(times) ? times : 1;- 12
if (!times) {//make sure times is greater than zero if it is zero then dont multiply it- 3
times = 1;}- 12
arr = toArray(arr || []);- 12
var ret = [], i = 0;- 12
while (++i <= times) {- 15
ret = ret.concat(arr);}- 12
return ret;}/*** Flatten multiple arrays into a single array** @example** comb.array.flatten([1,2], [2,3], [3,4]) => [1,2,2,3,3,4]* comb.array.flatten([1,"A"], [2,"B"], [3,"C"]) => [1,"A",2,"B",3,"C"]** @param array** @static* @memberOf comb.array*/- 1
function flatten(arr) {- 71
var set;- 71
var args = argsToArray(arguments);- 71
if (args.length > 1) {//assume we are intersections all the lists in the array- 10
set = args;} else {- 61
set = toArray(arr);}- 71
return reduce(set, function (a, b) {- 127
return a.concat(b);}, []);}/*** Plucks values from an array. Effectevily the same as using a array.map implementation. However the porperty specified supports* a "dot" notation to access nested properties.** @example** var arr = [* {name:{first:"Fred", last:"Jones"}, age:50, roles:["a", "b", "c"]},* {name:{first:"Bob", last:"Yukon"}, age:40, roles:["b", "c"]},* {name:{first:"Alice", last:"Palace"}, age:35, roles:["c"]},* {name:{first:"Johnny", last:"P."}, age:56, roles:[]}* ];* console.log(comb.array.pluck(arr, "name.first")); //["Fred", "Bob", "Alice", "Johnny"]* console.log(comb.array.pluck(arr, "age")); //[50, 40, 35, 56]* console.log(comb.array.pluck(arr, "roles.length")); //[3, 2, 1, 0]* console.log(comb.array.pluck(arr, "roles.0")); //["a", "b", "c", undefined]** @param {Array} arr the array to pluck values from* @param {String} prop the property to retrieve from each item in the array* @return {Array} an array containing the plucked properties.** @static* @memberOf comb.array*/- 1
function pluck(arr, prop) {- 7
prop = prop.split(".");- 7
var result = arr.slice(0);- 7
forEach(prop, function (prop) {- 13
var exec = prop.match(/(\w+)\(\)$/);- 13
result = map(result, function (item) {- 52
return exec ? item[exec[1]]() : item[prop];});});- 7
return result;}/*** Invokes the method specified in the scope of each item in the array. If you supply addional arguments they will* be applied to the function.** ```** function person(name, age){* return {* getName : function(){* return name;* },* setName : function(newName){* name = newName;* },** getOlder : function(){* age++;* return this;* },** getAge : function(){* return age;* }* };* }** var arr = [person("Bob", 40), person("Alice", 35), person("Fred", 50), person("Johnny", 56)];** console.log(comb.array.invoke(arr, "getName")); //["Bob", "Alice", "Fred", "Johnny"]** console.log(comb.array(arr).invoke("getOlder").invoke("getAge")); //[41, 36, 51, 57];** ```** @param {Array} arr the array to iterate and invoke the functions on* @param {String|Function} func the function to invoke, if it is a string then the function will be looked up on the* each item in the array and invoked* @param [args=null] variable number of arguments to apply to the function* @return {Array} the return values of the functions invoked.** @static* @memberOf comb.array*/- 1
function invoke(arr, func, args) {- 8
args = argsToArray(arguments, 2);- 8
return map(arr, function (item) {- 32
var exec = isString(func) ? item[func] : func;- 32
return exec.apply(item, args);});}- 1
var comb = exports;/*** @namespace Utilities for working with arrays.** The `comb.array` namespace can be used to decorate arrays with additional chainable funcitonality.** ```** var arr = comb.array([1,3,2,5,4,6]);* console.log(arr.sum()) //21* console.log(arr.sort()) //[1,2,3,4,5,6]* console.log(arr.min()) //[1]* console.log(arr.max()) [6]** ```** @function* @ignoreCode*/- 1
comb.array = {toArray:toArray,sum:sum,avg:avg,sort:sort,min:min,max:max,difference:difference,removeDuplicates:removeDuplicates,unique:unique,rotate:rotate,permutations:permutations,zip:zip,transpose:transpose,valuesAt:valuesAt,union:union,intersect:intersect,powerSet:powerSet,cartesian:cartesian,compact:compact,multiply:multiply,flatten:flatten,pluck:pluck,invoke:invoke,forEach:forEach,map:map,filter:filter,reduce:reduce,reduceRight:reduceRight,some:some,every:every,indexOf:indexOf,lastIndexOf:lastIndexOf};
|
base/broadcast.js
|
Coverage100.00
SLOC171
LOC63
Missed0
|
- 1
var func = require("./functions"),obj = require("./object");- 1
var comb = exports;- 1
var wrapper = function() {- 8
return function() {- 31
var c = arguments.callee, listeners = c.__listeners, func = c.func, r;- 31
if (func) {- 31
r = func.apply(this, arguments);}- 31
for (var i = 0; i < listeners.length; i++) {- 39
var lis = listeners[i];- 39
if (lis) {- 30
lis.apply(this, arguments);}}- 31
return r;}};- 1
var listeners = {};- 1
obj.merge(comb, {/**@lends comb*//*** Disconnects a listener to a function* @param {handle} A handle returned from comb.connect*/disconnect : function(handle) {- 10
if (handle && handle.length == 3) {- 9
var obj = handle[0], method = handle[1], cb = handle[2];- 9
if (typeof method != "string") throw "comb.disconnect : When calling disconnect the method must be string";- 9
var scope = obj || global, ls;- 9
if (typeof scope[method] == "function") {- 8
ls = scope[method].__listeners;- 8
if (ls && cb-- > 0) {//we dont want to splice it because our indexing will get off- 8
ls[cb] = null;}} else {- 1
throw new Error("unknown method " + method + " in object " + obj);}} else {- 1
throw "comb.disconnect : invalid handle"}},/*** Function to listen when other functions are called** @example** comb.connect(obj, "event", myfunc);* comb.connect(obj, "event", "log", console);** @param {Object} obj the object in which the method you are connecting to resides* @param {String} method the name of the method to connect to* @param {Function} cb the function to callback* @param {Object} [scope] the scope to call the specified cb in** @returns {Array} handle to pass to {@link comb.disconnect}*/connect : function(obj, method, cb, scope) {- 14
var index;- 14
if (typeof method != "string") throw new Error("When calling connect the method must be string");- 14
if (!func.isFunction(cb)) throw new Error("When calling connect callback must be a string");- 14
var scope = obj || global, listeners, newMethod;- 14
if (typeof scope[method] == "function") {- 13
listeners = scope[method].__listeners;- 13
if (!listeners) {- 8
newMethod = wrapper();- 8
newMethod.func = obj[method];- 8
listeners = (newMethod.__listeners = []);- 8
scope[method] = newMethod;}- 13
index = listeners.push(cb);} else {- 1
throw new Error("unknow method " + method + " in object " + obj);}- 13
return [obj, method, index];},/*** Broadcasts an event to all listeners* NOTE : the function takes a variable number of arguments* i.e. all arguments after the topic will be passed to the listeners** @example*** comb.broadcast("hello", "hello world");* //the args "hello" and "world" will be passed to any listener of the topic* //"hello"* comb.broadcast("hello", "hello", "world");** @param {String} topic the topic to brodcast* @param params the information to bradcast*/broadcast : function() {- 4
var args = Array.prototype.slice.call(arguments);- 4
var topic = args.splice(0, 1)[0];- 4
if (topic) {- 4
var list = listeners[topic];- 4
if (list) {- 4
for (var i = list.length - 1; i >= 0; i--) {- 4
var han = list[i], cb = han.cb;- 4
if (cb) {- 4
cb.apply(this, args);}}}}},/*** Listen for the broadcast of certain events** @example* comb.listen("hello", function(arg1, arg2){* console.log(arg1);* console.log(arg2);* });** @param {String} topic the topic to listen for* @param {Function} callback the funciton to call when the topic is published** @returns a handle to pass to {@link comb.unListen}*/listen : function(topic, callback) {- 3
if (!func.isFunction(callback)) throw new Error("callback must be a function");- 3
var handle = {topic : topic,cb : callback,pos : null};- 3
var list = listeners[topic];- 3
if (!list) {- 3
list = (listeners[topic] = []);}- 3
list.push(handle);- 3
handle.pos = list.length - 1;- 3
return handle;},/*** Disconnects a listener** @param handle a handle returned from {@link comb.listen}*/unListen : function(handle) {- 2
if (handle) {- 2
var topic = handle.topic, list = listeners[topic];- 2
if (list) {- 2
for (var i = list.length - 1; i >= 0; i--) {- 2
if (list[i] == handle) {- 2
list.splice(i, 1);}}- 2
if (!list.length) {- 2
delete listeners[topic];}}}}});
|
base/date/index.js
|
Coverage100.00
SLOC885
LOC294
Missed0
|
- 1
var string = require("./../string").string,transforms = require("./transforms.js"),addTransform = transforms.addTransform,differenceTransform = transforms.differenceTransform;/*** @ignore* Based on DOJO Date Implementation** Dojo is available under *either* the terms of the modified BSD license *or* the* Academic Free License version 2.1. As a recipient of Dojo, you may choose which* license to receive this code under (except as noted in per-module LICENSE* files). Some modules may not be the copyright of the Dojo Foundation. These* modules contain explicit declarations of copyright in both the LICENSE files in* the directories in which they reside and in the code itself. No external* contributions are allowed under licenses which are fundamentally incompatible* with the AFL or BSD licenses that Dojo is distributed under.**/- 1
var floor = Math.floor, round = Math.round, min = Math.min, pow = Math.pow, ceil = Math.ceil, abs = Math.abs;- 1
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];- 1
var monthAbbr = ["Jan.", "Feb.", "Mar.", "Apr.", "May.", "Jun.", "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."];- 1
var monthLetter = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"];- 1
var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];- 1
var dayAbbr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];- 1
var dayLetter = ["S", "M", "T", "W", "T", "F", "S"];- 1
var eraNames = ["Before Christ", "Anno Domini"];- 1
var eraAbbr = ["BC", "AD"];- 1
var eraLetter = ["B", "A"];- 1
var comb = exports, date;/*** Determines if obj is a Date** @param {Anything} obj the thing to test if it is a Date* @memberOf comb* @returns {Boolean} true if it is a Date false otherwise*/- 1
comb.isDate = function (obj) {- 1232
var undef;- 1232
return (obj !== undef && typeof obj === "object" && obj instanceof Date);};- 1
function getDayOfYear(/*Date*/dateObject, utc) {// summary: gets the day of the year as represented by dateObject- 6
return date.difference(new Date(dateObject.getFullYear(), 0, 1, dateObject.getHours()), dateObject, null, utc) + 1; // Number}- 1
function getWeekOfYear(/*Date*/dateObject, /*Number*/firstDayOfWeek, utc) {- 4
firstDayOfWeek = firstDayOfWeek || 0;- 4
var fullYear = dateObject[utc ? "getUTCFullYear" : "getFullYear"]();- 4
var firstDayOfYear = new Date(fullYear, 0, 1).getDay(),adj = (firstDayOfYear - firstDayOfWeek + 7) % 7,week = floor((getDayOfYear(dateObject) + adj - 1) / 7);// if year starts on the specified day, start counting weeks at 1- 4
if (firstDayOfYear === firstDayOfWeek) {- 4
week++;}- 4
return week; // Number}- 1
function getTimezoneName(/*Date*/dateObject) {- 37
var str = dateObject.toString();- 37
var tz = '';- 37
var pos = str.indexOf('(');- 37
if (pos > -1) {- 33
tz = str.substring(++pos, str.indexOf(')'));}- 37
return tz; // String}- 1
function buildDateEXP(pattern, tokens) {- 55
return pattern.replace(/([a-z])\1*/ig,function (match) {// Build a simple regexp. Avoid captures, which would ruin the tokens list- 197
var s,c = match.charAt(0),l = match.length,p2 = '', p3 = '';- 197
p2 = '0?';- 197
p3 = '0{0,2}';- 197
if (c === 'y') {- 33
s = '\\d{2,4}';- 164
} else if (c === "M") {- 33
s = (l > 2) ? '\\S+?' : '1[0-2]|' + p2 + '[1-9]';- 131
} else if (c === "D") {- 4
s = '[12][0-9][0-9]|3[0-5][0-9]|36[0-6]|' + p3 + '[1-9][0-9]|' + p2 + '[1-9]';- 127
} else if (c === "d") {- 31
s = '3[01]|[12]\\d|' + p2 + '[1-9]';- 96
} else if (c === "w") {- 4
s = '[1-4][0-9]|5[0-3]|' + p2 + '[1-9]';- 92
} else if (c === "E") {- 12
s = '\\S+';- 80
} else if (c === "h") {- 10
s = '1[0-2]|' + p2 + '[1-9]';- 70
} else if (c === "K") {- 4
s = '1[01]|' + p2 + '\\d';- 66
} else if (c === "H") {- 2
s = '1\\d|2[0-3]|' + p2 + '\\d';- 64
} else if (c === "k") {- 2
s = '1\\d|2[0-4]|' + p2 + '[1-9]';- 62
} else if (c === "m" || c === "s") {- 30
s = '[0-5]\\d';- 32
} else if (c === "S") {- 10
s = '\\d{' + l + '}';- 22
} else if (c === "a") {- 6
var am = 'AM', pm = 'PM';- 6
s = am + '|' + pm;- 6
if (am !== am.toLowerCase()) {- 6
s += '|' + am.toLowerCase();}- 6
if (pm !== pm.toLowerCase()) {- 6
s += '|' + pm.toLowerCase();}- 6
s = s.replace(/\./g, "\\.");- 16
} else if (c === 'v' || c === 'z' || c === 'Z' || c === 'G' || c === 'q' || c === 'Q') {- 12
s = ".*";} else {- 4
s = c === " " ? "\\s*" : c + "*";}- 197
if (tokens) {- 197
tokens.push(match);}- 197
return "(" + s + ")"; // add capture}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace. Need explicit handling of \xa0 for IE.}/*** @namespace Utilities for Dates*/- 1
comb.date = {/**@lends comb.date*//*** Returns the number of days in the month of a date** @example** comb.date.getDaysInMonth(new Date(2006, 1, 1)); //28* comb.date.getDaysInMonth(new Date(2004, 1, 1)); //29* comb.date.getDaysInMonth(new Date(2006, 2, 1)); //31* comb.date.getDaysInMonth(new Date(2006, 3, 1)); //30* comb.date.getDaysInMonth(new Date(2006, 4, 1)); //31* comb.date.getDaysInMonth(new Date(2006, 5, 1)); //30* comb.date.getDaysInMonth(new Date(2006, 6, 1)); //31* @param {Date} dateObject the date containing the month* @return {Number} the number of days in the month*/getDaysInMonth:function (/*Date*/dateObject) {// summary:// Returns the number of days in the month used by dateObject- 36
var month = dateObject.getMonth();- 36
var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];- 36
if (month === 1 && date.isLeapYear(dateObject)) {- 6
return 29;} // Number- 30
return days[month]; // Number},/*** Determines if a date is a leap year** @example** comb.date.isLeapYear(new Date(1600, 0, 1)); //true* comb.date.isLeapYear(new Date(2004, 0, 1)); //true* comb.date.isLeapYear(new Date(2000, 0, 1)); //true* comb.date.isLeapYear(new Date(2006, 0, 1)); //false* comb.date.isLeapYear(new Date(1900, 0, 1)); //false* comb.date.isLeapYear(new Date(1800, 0, 1)); //false* comb.date.isLeapYear(new Date(1700, 0, 1)); //false** @param {Date} dateObject* @returns {Boolean} true if it is a leap year false otherwise*/isLeapYear:function (/*Date*/dateObject, utc) {- 28
var year = dateObject[utc ? "getUTCFullYear" : "getFullYear"]();- 28
return (year % 400 === 0) || (year % 4 === 0 && year % 100 !== 0);},/*** Determines if a date is on a weekend** @example** var thursday = new Date(2006, 8, 21);* var saturday = new Date(2006, 8, 23);* var sunday = new Date(2006, 8, 24);* var monday = new Date(2006, 8, 25);* comb.date.isWeekend(thursday)); //false* comb.date.isWeekend(saturday); //true* comb.date.isWeekend(sunday); //true* comb.date.isWeekend(monday)); //false** @param {Date} dateObject the date to test** @returns {Boolean} true if the date is a weekend*/isWeekend:function (/*Date?*/dateObject, utc) {// summary:// Determines if the date falls on a weekend, according to local custom.- 4
var day = (dateObject || new Date())[utc ? "getUTCDay" : "getDay"]();- 4
return day === 0 || day === 6;},/*** Get the timezone of a date** @example* //just setting the strLocal to simulate the toString() of a date* dt.str = 'Sun Sep 17 2006 22:25:51 GMT-0500 (CDT)';* //just setting the strLocal to simulate the locale* dt.strLocale = 'Sun 17 Sep 2006 10:25:51 PM CDT';* comb.date.getTimezoneName(dt); //'CDT'* dt.str = 'Sun Sep 17 2006 22:57:18 GMT-0500 (CDT)';* dt.strLocale = 'Sun Sep 17 22:57:18 2006';* comb.date.getTimezoneName(dt); //'CDT'* @param dateObject the date to get the timezone from** @returns {String} the timezone of the date*/getTimezoneName:getTimezoneName,/*** Compares two dates** @example** var d1 = new Date();* d1.setHours(0);* comb.date.compare(d1, d1); // 0** var d1 = new Date();* d1.setHours(0);* var d2 = new Date();* d2.setFullYear(2005);* d2.setHours(12);* comb.date.compare(d1, d2, "date"); // 1* comb.date.compare(d1, d2, "datetime"); // 1** var d1 = new Date();* d1.setHours(0);* var d2 = new Date();* d2.setFullYear(2005);* d2.setHours(12);* comb.date.compare(d2, d1, "date"); // -1* comb.date.compare(d1, d2, "time"); //-1** @param {Date|String} date1 the date to comapare* @param {Date|String} [date2=new Date()] the date to compare date1 againse* @param {"date"|"time"|"datetime"} portion compares the portion specified** @returns -1 if date1 is < date2 0 if date1 === date2 1 if date1 > date2*/compare:function (/*Date*/date1, /*Date*/date2, /*String*/portion) {- 10
date1 = new Date(date1);- 10
date2 = new Date((date2 || new Date()));- 10
if (portion === "date") {// Ignore times and compare dates.- 4
date1.setHours(0, 0, 0, 0);- 4
date2.setHours(0, 0, 0, 0);- 6
} else if (portion === "time") {// Ignore dates and compare times.- 2
date1.setFullYear(0, 0, 0);- 2
date2.setFullYear(0, 0, 0);}- 10
return date1 > date2 ? 1 : date1 < date2 ? -1 : 0;},/*** Adds a specified interval and amount to a date** @example* var dtA = new Date(2005, 11, 27);* comb.date.add(dtA, "year", 1); //new Date(2006, 11, 27);* comb.date.add(dtA, "years", 1); //new Date(2006, 11, 27);** dtA = new Date(2000, 0, 1);* comb.date.add(dtA, "quarter", 1); //new Date(2000, 3, 1);* comb.date.add(dtA, "quarters", 1); //new Date(2000, 3, 1);** dtA = new Date(2000, 0, 1);* comb.date.add(dtA, "month", 1); //new Date(2000, 1, 1);* comb.date.add(dtA, "months", 1); //new Date(2000, 1, 1);** dtA = new Date(2000, 0, 31);* comb.date.add(dtA, "month", 1); //new Date(2000, 1, 29);* comb.date.add(dtA, "months", 1); //new Date(2000, 1, 29);** dtA = new Date(2000, 0, 1);* comb.date.add(dtA, "week", 1); //new Date(2000, 0, 8);* comb.date.add(dtA, "weeks", 1); //new Date(2000, 0, 8);** dtA = new Date(2000, 0, 1);* comb.date.add(dtA, "day", 1); //new Date(2000, 0, 2);** dtA = new Date(2000, 0, 1);* comb.date.add(dtA, "weekday", 1); //new Date(2000, 0, 3);** dtA = new Date(2000, 0, 1, 11);* comb.date.add(dtA, "hour", 1); //new Date(2000, 0, 1, 12);** dtA = new Date(2000, 11, 31, 23, 59);* comb.date.add(dtA, "minute", 1); //new Date(2001, 0, 1, 0, 0);** dtA = new Date(2000, 11, 31, 23, 59, 59);* comb.date.add(dtA, "second", 1); //new Date(2001, 0, 1, 0, 0, 0);** dtA = new Date(2000, 11, 31, 23, 59, 59, 999);* comb.date.add(dtA, "millisecond", 1); //new Date(2001, 0, 1, 0, 0, 0, 0);** @param {Date} date* @param {String} interval the interval to add* <ul>* <li>day | days</li>* <li>weekday | weekdays</li>* <li>year | years</li>* <li>week | weeks</li>* <li>quarter | quarters</li>* <li>months | months</li>* <li>hour | hours</li>* <li>minute | minutes</li>* <li>second | seconds</li>* <li>millisecond | milliseconds</li>* </ul>* @param {Number} [amount=0] the amount to add*/add:function (/*Date*/date, /*String*/interval, /*int*/amount) {- 228
var res = addTransform(interval, date, amount || 0);- 228
amount = res[0];- 228
var property = res[1];- 228
var sum = new Date(date);- 228
var fixOvershoot = res[2];- 228
if (property) {- 228
sum["set" + property](sum["get" + property]() + amount);}- 228
if (fixOvershoot && (sum.getDate() < date.getDate())) {- 26
sum.setDate(0);}- 228
return sum; // Date},/*** Finds the difference between two dates based on the specified interval** @example** var dtA, dtB;** dtA = new Date(2005, 11, 27);* dtB = new Date(2006, 11, 27);* comb.date.difference(dtA, dtB, "year"); //1** dtA = new Date(2000, 1, 29);* dtB = new Date(2001, 2, 1);* comb.date.difference(dtA, dtB, "quarter"); //4* comb.date.difference(dtA, dtB, "month"); //13** dtA = new Date(2000, 1, 1);* dtB = new Date(2000, 1, 8);* comb.date.difference(dtA, dtB, "week"); //1** dtA = new Date(2000, 1, 29);* dtB = new Date(2000, 2, 1);* comb.date.difference(dtA, dtB, "day"); //1** dtA = new Date(2006, 7, 3);* dtB = new Date(2006, 7, 11);* comb.date.difference(dtA, dtB, "weekday"); //6** dtA = new Date(2000, 11, 31, 23);* dtB = new Date(2001, 0, 1, 0);* comb.date.difference(dtA, dtB, "hour"); //1** dtA = new Date(2000, 11, 31, 23, 59);* dtB = new Date(2001, 0, 1, 0, 0);* comb.date.difference(dtA, dtB, "minute"); //1** dtA = new Date(2000, 11, 31, 23, 59, 59);* dtB = new Date(2001, 0, 1, 0, 0, 0);* comb.date.difference(dtA, dtB, "second"); //1** dtA = new Date(2000, 11, 31, 23, 59, 59, 999);* dtB = new Date(2001, 0, 1, 0, 0, 0, 0);* comb.date.difference(dtA, dtB, "millisecond"); //1*** @param {Date} date1* @param {Date} [date2 = new Date()]* @param {String} [interval = "day"] the intercal to find the difference of.* <ul>* <li>day | days</li>* <li>weekday | weekdays</li>* <li>year | years</li>* <li>week | weeks</li>* <li>quarter | quarters</li>* <li>months | months</li>* <li>hour | hours</li>* <li>minute | minutes</li>* <li>second | seconds</li>* <li>millisecond | milliseconds</li>* </ul>*/difference:function (/*Date*/date1, /*Date?*/date2, /*String*/interval, utc) {- 162
date2 = date2 || new Date();- 162
interval = interval || "day";- 162
return differenceTransform(interval, date1, date2, utc);},/*** Parses a date string into a date object** @example* var aug_11_2006 = new Date(2006, 7, 11, 0);* comb.date.parse("08/11/06", "MM/dd/yy"); //aug_11_2006* comb.date.parse("11Aug2006", 'ddMMMyyyy'); //aug_11_2006* comb.date.parse("Aug2006", 'MMMyyyy'); //new Date(2006, 7, 1)* comb.date.parse("Aug 11, 2006", "MMM dd, yyyy"); //aug_11_2006* comb.date.parse("August 11, 2006", "MMMM dd, yyyy"); //aug_11_2006* comb.date.parse("Friday, August 11, 2006", "EEEE, MMMM dd, yyyy"); //aug_11_2006** @param {String} dateStr The string to parse* @param {String} format the format of the date composed of the following options* <ul>* <li> G Era designator Text AD</li>* <li> y Year Year 1996; 96</li>* <li> M Month in year Month July; Jul; 07</li>* <li> w Week in year Number 27</li>* <li> W Week in month Number 2</li>* <li> D Day in year Number 189</li>* <li> d Day in month Number 10</li>* <li> E Day in week Text Tuesday; Tue</li>* <li> a Am/pm marker Text PM</li>* <li> H Hour in day (0-23) Number 0</li>* <li> k Hour in day (1-24) Number 24</li>* <li> K Hour in am/pm (0-11) Number 0</li>* <li> h Hour in am/pm (1-12) Number 12</li>* <li> m Minute in hour Number 30</li>* <li> s Second in minute Number 55</li>* <li> S Millisecond Number 978</li>* <li> z Time zone General time zone Pacific Standard Time; PST; GMT-08:00</li>* <li> Z Time zone RFC 822 time zone -0800 </li>* </ul>** @returns {Date} the parsed date***/parse:function (dateStr, format) {- 57
if (!format) {- 2
throw new Error('format required when calling comb.date.parse');}- 55
var tokens = [], regexp = buildDateEXP(format, tokens),re = new RegExp("^" + regexp + "$", "i"),match = re.exec(dateStr);- 55
if (!match) {- 7
return null;} // null- 48
var result = [1970, 0, 1, 0, 0, 0, 0], // will get converted to a Date at the endamPm = "",valid = match.every(function (v, i) {- 212
if (i) {- 164
var token = tokens[i - 1];- 164
var l = token.length, type = token.charAt(0);- 164
if (type === 'y') {- 26
if (v < 100) {- 6
v = parseInt(v, 10);//choose century to apply, according to a sliding window//of 80 years before and 20 years after present year- 6
var year = '' + new Date().getFullYear(),century = year.substring(0, 2) * 100,cutoff = min(year.substring(2, 4) + 20, 99);- 6
result[0] = (v < cutoff) ? century + v : century - 100 + v;} else {- 20
result[0] = v;}- 138
} else if (type === "M") {- 28
if (l > 2) {- 20
var months = monthNames;- 20
if (l === 3) {- 8
months = monthAbbr;}//Tolerate abbreviating period in month part//Case-insensitive comparison- 20
v = v.replace(".", "").toLowerCase();- 20
months = months.map(function (s) {- 240
return s.replace(".", "").toLowerCase();});- 20
if ((v = months.indexOf(v)) === -1) {- 2
return false;}} else {- 8
v--;}- 26
result[1] = v;- 110
} else if (type === "E" || type === "e") {- 12
var days = dayNames;- 12
if (l === 3) {- 4
days = dayAbbr;}//Case-insensitive comparison- 12
v = v.toLowerCase();- 12
days = days.map(function (d) {- 84
return d.toLowerCase();});- 12
var d = days.indexOf(v);- 12
if (d === -1) {- 4
v = parseInt(v, 10);- 4
if (isNaN(v) || v > days.length) {- 2
return false;}} else {- 8
v = d;}- 98
} else if (type === 'D' || type === "d") {- 30
if (type === "D") {- 4
result[1] = 0;}- 30
result[2] = v;- 68
} else if (type === "a") {- 4
var am = "am";- 4
var pm = "pm";- 4
var period = /\./g;- 4
v = v.replace(period, '').toLowerCase();// we might not have seen the hours field yet, so store the state and apply hour change later- 4
amPm = (v === pm) ? 'p' : (v === am) ? 'a' : '';- 64
} else if (type === "k" || type === "h" || type === "H" || type === "K") {- 14
if (type === "k" && (+v) === 24) {- 2
v = 0;}- 14
result[3] = v;- 50
} else if (type === "m") {- 14
result[4] = v;- 36
} else if (type === "s") {- 10
result[5] = v;- 26
} else if (type === "S") {- 8
result[6] = v;}}- 208
return true;});- 48
if (valid) {- 44
var hours = +result[3];//account for am/pm- 44
if (amPm === 'p' && hours < 12) {- 2
result[3] = hours + 12; //e.g., 3pm -> 15- 42
} else if (amPm === 'a' && hours === 12) {- 2
result[3] = 0; //12am -> 0}- 44
var dateObject = new Date(result[0], result[1], result[2], result[3], result[4], result[5], result[6]); // Date- 44
var dateToken = (tokens.indexOf('d') !== -1),monthToken = (tokens.indexOf('M') !== -1),month = result[1],day = result[2],dateMonth = dateObject.getMonth(),dateDay = dateObject.getDate();- 44
if ((monthToken && dateMonth > month) || (dateToken && dateDay > day)) {- 2
return null;}- 42
return dateObject; // Date} else {- 4
return null;}},/*** Formats a date to the specidifed format string** @example** var date = new Date(2006, 7, 11, 0, 55, 12, 345);* comb.date.format(date, "EEEE, MMMM dd, yyyy"); //"Friday, August 11, 2006"* comb.date.format(date, "M/dd/yy"); //"8/11/06"* comb.date.format(date, "E"); //"6"* comb.date.format(date, "h:m a"); //"12:55 AM"* comb.date.format(date, 'h:m:s'); //"12:55:12"* comb.date.format(date, 'h:m:s.SS'); //"12:55:12.35"* comb.date.format(date, 'k:m:s.SS'); //"24:55:12.35"* comb.date.format(date, 'H:m:s.SS'); //"0:55:12.35"* comb.date.format(date, "ddMMyyyy"); //"11082006"** @param date the date to format* @param {String} format the format of the date composed of the following options* <ul>* <li> G Era designator Text AD</li>* <li> y Year Year 1996; 96</li>* <li> M Month in year Month July; Jul; 07</li>* <li> w Week in year Number 27</li>* <li> W Week in month Number 2</li>* <li> D Day in year Number 189</li>* <li> d Day in month Number 10</li>* <li> E Day in week Text Tuesday; Tue</li>* <li> a Am/pm marker Text PM</li>* <li> H Hour in day (0-23) Number 0</li>* <li> k Hour in day (1-24) Number 24</li>* <li> K Hour in am/pm (0-11) Number 0</li>* <li> h Hour in am/pm (1-12) Number 12</li>* <li> m Minute in hour Number 30</li>* <li> s Second in minute Number 55</li>* <li> S Millisecond Number 978</li>* <li> z Time zone General time zone Pacific Standard Time; PST; GMT-08:00</li>* <li> Z Time zone RFC 822 time zone -0800 </li>* </ul>*/format:function (date, format, utc) {- 78
utc = utc || false;- 78
var fullYear, month, day, d, hour, minute, second, millisecond;- 78
if (utc) {- 26
fullYear = date.getUTCFullYear();- 26
month = date.getUTCMonth();- 26
day = date.getUTCDay();- 26
d = date.getUTCDate();- 26
hour = date.getUTCHours();- 26
minute = date.getUTCMinutes();- 26
second = date.getUTCSeconds();- 26
millisecond = date.getUTCMilliseconds();} else {- 52
fullYear = date.getFullYear();- 52
month = date.getMonth();- 52
d = date.getDate();- 52
day = date.getDay();- 52
hour = date.getHours();- 52
minute = date.getMinutes();- 52
second = date.getSeconds();- 52
millisecond = date.getMilliseconds();}- 78
return format.replace(/([A-Za-z])\1*/g, function (match, options) {- 372
var s, pad, h,c = match.charAt(0),l = match.length;- 372
if (c === 'd') {- 42
s = "" + d;- 42
pad = true;- 330
} else if (c === "H" && !s) {- 30
s = "" + hour;- 30
pad = true;- 300
} else if (c === 'm' && !s) {- 40
s = "" + minute;- 40
pad = true;- 260
} else if (c === 's') {- 38
if (!s) {- 38
s = "" + second;}- 38
pad = true;- 222
} else if (c === "G") {- 4
s = ((l < 4) ? eraAbbr : eraNames)[fullYear < 0 ? 0 : 1];- 218
} else if (c === "y") {- 48
s = fullYear;- 48
if (l > 1) {- 48
if (l === 2) {- 6
s = string.truncate("" + s, 2, true);} else {- 42
pad = true;}}- 170
} else if (c.toUpperCase() === "Q") {- 6
s = ceil((month + 1) / 3);- 6
pad = true;- 164
} else if (c === "M") {- 42
if (l < 3) {- 32
s = month + 1;- 32
pad = true;} else {- 10
s = (l === 3 ? monthAbbr : monthNames)[month];}- 122
} else if (c === "w") {- 4
s = getWeekOfYear(date, 0, utc);- 4
pad = true;- 118
} else if (c === "D") {- 2
s = getDayOfYear(date, utc);- 2
pad = true;- 116
} else if (c === "E") {- 12
if (l < 3) {- 2
s = day + 1;- 2
pad = true;} else {- 10
s = (l === -3 ? dayAbbr : dayNames)[day];}- 104
} else if (c === 'a') {- 2
s = (hour < 12) ? 'AM' : 'PM';- 102
} else if (c === "h") {- 6
s = (hour % 12) || 12;- 6
pad = true;- 96
} else if (c === "K") {- 2
s = (hour % 12);- 2
pad = true;- 94
} else if (c === "k") {- 2
s = hour || 24;- 2
pad = true;- 92
} else if (c === "S") {- 36
s = round(millisecond * pow(10, l - 3));- 36
pad = true;- 56
} else if (c === "z" || c === "v" || c === "Z") {- 30
s = getTimezoneName(date);- 30
if ((c === "z" || c === "v") && !s) {- 4
l = 4;}- 30
if (!s || c === "Z") {- 4
var offset = date.getTimezoneOffset();- 4
var tz = [(offset >= 0 ? "-" : "+"),string.pad(floor(abs(offset) / 60), 2, "0"),string.pad(abs(offset) % 60, 2, "0")];- 4
if (l === 4) {- 4
tz.splice(0, 0, "GMT");- 4
tz.splice(3, 0, ":");}- 4
s = tz.join("");}} else {- 26
s = match;}- 372
if (pad) {- 284
s = string.pad(s, l, '0');}- 372
return s;});}};- 1
date = comb.date;/*** Adds the specified year/s to the current date.** @example** //assuming that current year is 2012* comb.yearsFromNow(1); //2013-mm-dd hh:MM:ss** @param {Number} val the number of years to add** @return {Date} a date with the number of years added*/- 1
comb.yearsFromNow = function (val) {- 1
return date.add(new Date(), "years", val);};/*** Subtracts the specified year/s from the current date.** @param {Number} val the number of years to subtract** @return {Date} a date with the number of years subtracted*/- 1
comb.yearsAgo = function (val) {- 1
return date.add(new Date(), "years", -val);};/*** Adds the specified month/s to the current date.** @example** //assuming that current month is february* comb.yearsFromNow(2); //yyyy-04-dd hh:MM:ss** @param {Number} val the number of months to add** @return {Date} a date with the number of years added*/- 1
comb.monthsFromNow = function (val) {- 1
return date.add(new Date(), "months", val);};/*** Subtracts the specified month/s from the current date.** @param {Number} val the number of months to subtract** @return {Date} a date with the number of months subtracted*/- 1
comb.monthsAgo = function (val) {- 1
return date.add(new Date(), "months", -val);};/*** Adds the specified day/s to the current date.** @param {Number} val the number of days to add** @return {Date} a date with the number of days added*/- 1
comb.daysFromNow = function (val) {- 27
return date.add(new Date(), "days", val);};/*** Subtracts the specified day/s from the current date.** @param {Number} val the number of days to subtract** @return {Date} a date with the number of days subtracted*/- 1
comb.daysAgo = function (val) {- 1
return date.add(new Date(), "days", -val);};/*** Adds the specified hour/s to the current date.** @param {Number} val the number of hours to add** @return {Date} a date with the number of hours added*/- 1
comb.hoursFromNow = function (val) {- 1
return date.add(new Date(), "hours", val);};/*** Subtracts the specified hour/s from the current date.** @param {Number} val the number of hours to subtract** @return {Date} a date with the number of hours subtracted*/- 1
comb.hoursAgo = function (val) {- 1
return date.add(new Date(), "hours", -val);};/*** Adds the specified minute/s to the current date.** @param {Number} val the number of minutes to add** @return {Date} a date with the number of minutes added*/- 1
comb.minutesFromNow = function (val) {- 1
return date.add(new Date(), "minutes", val);};/*** Subtracts the specified minute/s from the current date.** @param {Number} val the number of minutes to subtract** @return {Date} a date with the number of minutes subtracted*/- 1
comb.minutesAgo = function (val) {- 1
return date.add(new Date(), "minutes", -val);};/*** Adds the specified second/s to the current date.** @param {Number} val the number of seconds to add** @return {Date} a date with the number of seconds added*/- 1
comb.secondsFromNow = function (val) {- 1
return date.add(new Date(), "seconds", val);};/*** Subtracts the specified second/s from the current date.** @param {Number} val the number of seconds to subtract** @return {Date} a date with the number of seconds subtracted*/- 1
comb.secondsAgo = function (val) {- 1
return date.add(new Date(), "seconds", -val);};
|
base/date/transforms.js
|
Coverage100.00
SLOC148
LOC75
Missed0
|
- 1
var floor = Math.floor, round = Math.round, min = Math.min, pow = Math.pow, ceil = Math.ceil, abs = Math.abs;- 1
var addMap = {day:function addDay(date, amount) {- 62
return [amount, "Date", false];},weekday:function addWeekday(date, amount) {// Divide the increment time span into weekspans plus leftover days// e.g., 8 days is one 5-day weekspan / and two leftover days// Can't have zero leftover days, so numbers divisible by 5 get// a days value of 5, and the remaining days make up the number of weeks- 32
var days, weeks, mod = amount % 5, strt = date.getDay(), adj = 0;- 32
if (!mod) {- 12
days = (amount > 0) ? 5 : -5;- 12
weeks = (amount > 0) ? ((amount - 5) / 5) : ((amount + 5) / 5);} else {- 20
days = mod;- 20
weeks = parseInt(amount / 5, 10);}- 32
if (strt === 6 && amount > 0) {- 4
adj = 1;- 28
} else if (strt === 0 && amount < 0) {// Orig date is Sun / negative increment// Jump back over Sat- 8
adj = -1;}// Get weekday val for the new date- 32
var trgt = strt + days;// New date is on Sat or Sun- 32
if (trgt === 0 || trgt === 6) {- 4
adj = (amount > 0) ? 2 : -2;}// Increment by number of weeks plus leftover days plus// weekend adjustments- 32
return [(7 * weeks) + days + adj, "Date", false];},year:function addYear(date, amount) {- 36
return [amount, "FullYear", true];},week:function addWeek(date, amount) {- 6
return [amount * 7, "Date", false];},quarter:function addYear(date, amount) {- 18
return [amount * 3, "Month", true];},month:function addYear(date, amount) {- 22
return [amount, "Month", true];}};- 1
function addTransform(interval, date, amount) {- 228
interval = interval.replace(/s$/, "");- 228
if (addMap.hasOwnProperty(interval)) {- 176
return addMap[interval](date, amount);}- 52
return [amount, "UTC" + interval.charAt(0).toUpperCase() + interval.substring(1) + "s", false];}- 1
var differenceMap = {"quarter":function quarterDifference(date1, date2, utc) {- 10
var yearDiff = date2.getFullYear() - date1.getFullYear();- 10
var m1 = date1[utc ? "getUTCMonth" : "getMonth"]();- 10
var m2 = date2[utc ? "getUTCMonth" : "getMonth"]();// Figure out which quarter the months are in- 10
var q1 = floor(m1 / 3) + 1;- 10
var q2 = floor(m2 / 3) + 1;// Add quarters for any year difference between the dates- 10
q2 += (yearDiff * 4);- 10
return q2 - q1;},"weekday":function weekdayDifference(date1, date2, utc) {- 56
var days = differenceTransform("day", date1, date2, utc), weeks;- 56
var mod = days % 7;// Even number of weeks- 56
if (mod === 0) {- 14
days = differenceTransform("week", date1, date2, utc) * 5;} else {// Weeks plus spare change (< 7 days)- 42
var adj = 0, aDay = date1[utc ? "getUTCDay" : "getDay"](), bDay = date2[utc ? "getUTCDay" : "getDay"]();- 42
weeks = parseInt(days / 7, 10);// Mark the date advanced by the number of// round weeks (may be zero)- 42
var dtMark = new Date(date1);- 42
dtMark.setDate(dtMark[utc ? "getUTCDate" : "getDate"]() + (weeks * 7));- 42
var dayMark = dtMark[utc ? "getUTCDay" : "getDay"]();// Spare change days -- 6 or less- 42
if (days > 0) {- 24
if (aDay === 6 || bDay === 6) {- 6
adj = -1;- 18
} else if (aDay === 0) {- 8
adj = 0;- 10
} else if (bDay === 0 || (dayMark + mod) > 5) {- 4
adj = -2;}- 18
} else if (days < 0) {- 18
if (aDay === 6) {- 2
adj = 0;- 16
} else if (aDay === 0 || bDay === 0) {- 8
adj = 1;- 8
} else if (bDay === 6 || (dayMark + mod) < 0) {- 4
adj = 2;}}- 42
days += adj;- 42
days -= (weeks * 2);}- 56
return days;},year:function (date1, date2) {- 16
return date2.getFullYear() - date1.getFullYear();},month:function (date1, date2, utc) {- 10
var m1 = date1[utc ? "getUTCMonth" : "getMonth"]();- 10
var m2 = date2[utc ? "getUTCMonth" : "getMonth"]();- 10
return (m2 - m1) + ((date2.getFullYear() - date1.getFullYear()) * 12);},week:function (date1, date2, utc) {- 22
return round(differenceTransform("day", date1, date2, utc) / 7);},day:function (date1, date2) {- 106
return 1.1574074074074074e-8 * (date2.getTime() - date1.getTime());},hour:function (date1, date2) {- 12
return 2.7777777777777776e-7 * (date2.getTime() - date1.getTime());},minute:function (date1, date2) {- 8
return 0.000016666666666666667 * (date2.getTime() - date1.getTime());},second:function (date1, date2) {- 6
return 0.001 * (date2.getTime() - date1.getTime());},millisecond:function (date1, date2) {- 8
return date2.getTime() - date1.getTime();}};- 1
function differenceTransform(interval, date1, date2, utc) {- 254
interval = interval.replace(/s$/, "");- 254
return round(differenceMap[interval](date1, date2, utc));}- 1
exports.addTransform = addTransform;- 1
exports.differenceTransform = differenceTransform;
|
base/index.js
|
Coverage100.00
SLOC12
LOC2
Missed0
|
- 1
var objectBase = require("./object");- 1
objectBase.merge(exports, objectBase,require("./broadcast"),require("./functions"),require("./string"),require("./number"),require("./misc"),require("./date"),require("./array"),require("./regexp"),require("./inflections"));
|
base/inflections.js
|
Coverage100.00
SLOC215
LOC93
Missed0
|
/** A port of the Rails/Sequel inflections class* http://sequel.rubyforge.org/rdoc/classes/Sequel/Inflections.html*/- 1
var array = require("./array").array, misc = require("./misc");- 1
var comb = exports;- 1
var CAMELIZE_CONVERT_REGEXP = /_(.)/g;- 1
var DASH = '-';- 1
var UNDERSCORE = '_';- 1
var UNDERSCORE_CONVERT_REGEXP1 = /([A-Z]+)(\d+|[A-Z][a-z])/g;- 1
var UNDERSCORE_CONVERT_REGEXP2 = /(\d+|[a-z])(\d+|[A-Z])/g;- 1
var UNDERSCORE_CONVERT_REPLACE = '$1_$2';- 1
var PLURALS = [], SINGULARS = [], UNCOUNTABLES = [];- 1
var _plural = function (rule, replacement) {- 20
PLURALS.unshift([rule, replacement])};- 1
var _singular = function (rule, replacement) {- 23
SINGULARS.unshift([rule, replacement])};/*** Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used# for strings, not regular expressions. You simply pass the irregular in singular and plural form.## Examples:# irregular 'octopus', 'octopi'# irregular 'person', 'people'* @param singular the singular version* @param plural the plural version*/- 1
var _irregular = function (singular, plural) {- 7
_plural(new RegExp("(" + singular.substr(0, 1) + ")" + singular.substr(1) + "$"), "$1" + plural.substr(1));- 7
_singular(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$"), "$1" + singular.substr(1));};- 1
var _uncountable = function (words) {- 1
UNCOUNTABLES.push(misc.argsToArray(arguments))- 1
UNCOUNTABLES = array.flatten(UNCOUNTABLES);};- 1
_plural(/$/, 's');- 1
_plural(/s$/i, 's');- 1
_plural(/(alias|(?:stat|octop|vir|b)us)$/i, '$1es');- 1
_plural(/(buffal|tomat)o$/i, '$1oes');- 1
_plural(/([ti])um$/i, '$1a');- 1
_plural(/sis$/i, 'ses');- 1
_plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves');- 1
_plural(/(hive)$/i, '$1s');- 1
_plural(/([^aeiouy]|qu)y$/i, '$1ies');- 1
_plural(/(x|ch|ss|sh)$/i, '$1es');- 1
_plural(/(matr|vert|ind)ix|ex$/i, '$1ices');- 1
_plural(/([m|l])ouse$/i, '$1ice');- 1
_plural(/^(ox)$/i, "$1en");- 1
_singular(/s$/i, '');- 1
_singular(/([ti])a$/i, '$1um');- 1
_singular(/(analy|ba|cri|diagno|parenthe|progno|synop|the)ses$/i, '$1sis');- 1
_singular(/([^f])ves$/i, '$1fe');- 1
_singular(/([h|t]ive)s$/i, '$1');- 1
_singular(/([lr])ves$/i, '$1f');- 1
_singular(/([^aeiouy]|qu)ies$/i, '$1y');- 1
_singular(/(m)ovies$/i, '$1ovie');- 1
_singular(/(x|ch|ss|sh)es$/i, '$1');- 1
_singular(/([m|l])ice$/i, '$1ouse');- 1
_singular(/buses$/i, 'bus');- 1
_singular(/oes$/i, 'o');- 1
_singular(/shoes$/i, 'shoe');- 1
_singular(/(alias|(?:stat|octop|vir|b)us)es$/i, '$1');- 1
_singular(/(vert|ind)ices$/i, '$1ex');- 1
_singular(/matrices$/i, 'matrix');- 1
_irregular('person', 'people');- 1
_irregular('man', 'men');- 1
_irregular('child', 'children');- 1
_irregular('sex', 'sexes');- 1
_irregular('move', 'moves');- 1
_irregular('quiz', 'quizzes');- 1
_irregular('testis', 'testes');- 1
_uncountable("equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "news");- 1
exports.singular = _singular;- 1
exports.plural = _plural;- 1
exports.uncountable = _uncountable;/*** Converts a string to camelcase** @example* comb.camelize('hello_world') => helloWorld* comb.camelize('column_name') => columnName* comb.camelize('columnName') => columnName* comb.camelize(null) => null* comb.camelize() => undefined** @param {String} str the string to camelize* @memberOf comb* @returns {String} the camelized version of the string*/- 1
comb.camelize = function (str) {- 14
var ret = str;- 14
if (!misc.isUndefinedOrNull(str)) {- 12
ret = str.replace(CAMELIZE_CONVERT_REGEXP, function (a, b) {- 8
return b.toUpperCase();});}- 14
return ret;};/*** The reverse of camelize. Makes an underscored form from the expression in the string.** @example* comb.underscore('helloWorld') => hello_world* comb.underscore('column_name') => column_name* comb.underscore('columnName') => column_name* comb.underscore(null) => null* comb.underscore() => undefined* @param {String} str The string to underscore* @memberOf comb* @returns {String} the underscored version of the string* */- 1
comb.underscore = function (str) {- 12
var ret = str;- 12
if (!misc.isUndefinedOrNull(str)) {- 10
ret = str.replace(UNDERSCORE_CONVERT_REGEXP1, UNDERSCORE_CONVERT_REPLACE).replace(UNDERSCORE_CONVERT_REGEXP2, UNDERSCORE_CONVERT_REPLACE).replace(DASH, UNDERSCORE).toLowerCase();}- 12
return ret;};/*** Singularizes and camelizes the string. Also strips out all characters preceding* and including a period (".").** @example* comb.classify('egg_and_hams') => "eggAndHam"* comb.classify('post') => "post"* comb.classify('schema.post') => "post"** @param {String} str the string to classify* @memberOf comb* @returns {String} the classified version of the string**/- 1
comb.classify = function (str) {- 8
var ret = str;- 8
if (!misc.isUndefinedOrNull(str)) {- 6
ret = comb.camelize(comb.singularize(str.replace(/.*\./g, '')));}- 8
return ret;};/*** Returns the plural form of the word in the string.** @example* comb.pluralize("post") => "posts"* comb.pluralize("octopus") => "octopi"* comb.pluralize("sheep") => "sheep"* comb.pluralize("words") => "words"* comb.pluralize("the blue mailman") => "the blue mailmen"* comb.pluralize("CamelOctopus") => "CamelOctopi"** @param {String} str the string to pluralize* @memberOf comb* @returns {String} the pluralized version of the string**/- 1
comb.pluralize = function (str) {- 100
var ret = str;- 100
if (!misc.isUndefinedOrNull(str)) {- 98
if (UNCOUNTABLES.indexOf(str) == -1) {- 96
for (var i in PLURALS) {- 1282
var s = PLURALS[i], rule = s[0], replacement = s[1];- 1282
if ((ret = ret.replace(rule, replacement)) != str) {- 96
break;}}}}- 100
return ret;};/*** The reverse of pluralize, returns the singular form of a word in a string.** @example* comb.singularize("posts") => "post"* comb.singularize("octopi")=> "octopus"* comb.singularize("sheep") => "sheep"* comb.singularize("word") => "word"* comb.singularize("the blue mailmen") => "the blue mailman"* comb.singularize("CamelOctopi") => "CamelOctopus"** @param {String} str the string to singularize* @memberOf comb* @returns {String} the singularized version of the string* */- 1
comb.singularize = function (str) {- 106
var ret = str;- 106
if (!misc.isUndefinedOrNull(str)) {- 104
if (UNCOUNTABLES.indexOf(str) == -1) {- 102
for (var i in SINGULARS) {- 1570
var s = SINGULARS[i], rule = s[0], replacement = s[1];- 1570
if ((ret = ret.replace(rule, replacement)) != str) {- 98
break;}}}}- 106
return ret;};
|
base/misc.js
|
Coverage100.00
SLOC187
LOC51
Missed0
|
- 1
var comb = exports,arraySlice = Array.prototype.slice;/**** Converts an arguments object to an array** @example** function test(){* return comb.argsToArray(arguments);* }** function testSlice(){* return comb.argsToArray(arguments, 3);* }** console.log(test(1,2,3)); //[1,2,3]* console.log(test(1,2,3,4,5,6)); //[4,5,6]** @function* @param {Arguments} args the arguments object to convert* @param {Number} [slice=0] the number of arguments to slice.* @memberOf comb* @static* @returns {Array} array version of the arguments object*/- 1
function argsToArray(args, slice) {- 28644
slice = slice || 0;- 28644
return arraySlice.call(args, slice);}/*** Determines if obj is a boolean** @param {Anything} obj the thing to test if it is a boolean** @returns {Boolean} true if it is a boolean false otherwise* @memberOf comb* @static*/- 1
function isBoolean(obj) {- 12080
var undef, type = typeof obj;- 12080
return obj != undef && type == "boolean" || type == "Boolean";}/*** Determines if obj is undefined** @param {Anything} obj the thing to test if it is undefined* @returns {Boolean} true if it is undefined false otherwise* @memberOf comb* @static*/- 1
function isUndefined(obj) {- 14932
var undef;- 14932
return obj !== null && obj === undef;}/*** Determins if the obj is not undefined** @param obj the thing to test if it is not undefined** @return {Boolean} true if it is defined false otherwise* @memberOf comb* @static*/- 1
function isDefined(obj) {- 12
return !isUndefined(obj);}/*** Determines if obj is undefined or null** @param {Anything} obj the thing to test if it is undefined or null* @returns {Boolean} true if it is undefined or null false otherwise* @memberOf comb* @static*/- 1
function isUndefinedOrNull(obj) {- 14622
return isUndefined(obj) || isNull(obj);}/*** Determines if obj is null** @param {Anything} obj the thing to test if it is null** @returns {Boolean} true if it is null false otherwise* @memberOf comb* @static*/- 1
function isNull(obj) {- 14307
var undef;- 14307
return obj !== undef && obj == null;}/*** Determines if obj is an Arguments object;** @param {Anything} obj the thing to test if it is null** @returns {Boolean} true if it is an Arguments Object false otherwise* @memberOf comb* @static*/- 1
function isArguments(object) {- 1237
return !isUndefinedOrNull(object) && Object.prototype.toString.call(object) == '[object Arguments]';}- 1
function isInstance(obj, clazz) {- 12571
if (typeof clazz == "function") {- 12570
return obj instanceof clazz;} else {- 1
return false;}}/*** Determines if obj is an instance of a particular class** @param {Anything} obj the thing to test if it and instance of a class* @param {Object} Clazz used to determine if the object is an instance of** @returns {Boolean} true if it is an instance of the clazz false otherwise* @memberOf comb* @static*/- 1
function isInstanceOf(obj, clazz) {- 12571
return argsToArray(arguments, 1).some(function (c) {- 12571
return isInstance(obj, c);});}- 1
(function () {- 1
var listeners = [];- 1
var setup = false;- 1
function setupListener() {- 13
if (!setup) {- 1
var orig = process.emit;- 1
process.emit = function (event) {- 1
try {- 1
if (event === 'exit') {- 1
listeners.forEach(function (cb) {- 13
cb();});}} finally {- 1
orig.apply(this, arguments);}};- 1
setup = true;}}/*** Adds listeners to process.exit without having to change setMaxListeners useful if you* are writing a library and do not want to change core setting.** @param {Funciton} cb funciton to call when process is exiting* @memberOf comb* @static*/- 1
function listenForExit(cb) {- 13
setupListener();- 13
listeners.push(cb);}- 1
comb.listenForExit = listenForExit;})();- 1
comb.argsToArray = argsToArray;- 1
comb.isBoolean = isBoolean;- 1
comb.isUndefined = isUndefined;- 1
comb.isDefined = isDefined;- 1
comb.isUndefinedOrNull = isUndefinedOrNull;- 1
comb.isNull = isNull;- 1
comb.isArguments = isArguments;- 1
comb.isInstanceOf = isInstanceOf;
|
base/number.js
|
Coverage100.00
SLOC66
LOC10
Missed0
|
- 1
var comb = exports;/*** Determines if obj is a number** @param {Anything} obj the thing to test if it is a Number** @returns {Boolean} true if it is a number false otherwise*/- 1
comb.isNumber = function(obj) {- 2692
var undef;- 2692
return obj !== undef && obj != null && (typeof obj == "number" || obj instanceof Number);};/*** @private*/- 1
var round = Math.round, pow = Math.pow;/*** @namespace Utilities for numbers*/- 1
comb.number = {/**@lends comb.number*//*** Rounds a number to the specified places.** @example** comb.number.round(10.000009, 2); //10* comb.number.round(10.000009, 5); //10.00001* comb.number.round(10.0009, 3); //10.001* comb.number.round(10.0009, 2); //10* comb.number.round(10.0009, 3); //10.001** @param {Number} num the number to round.* @param {Number} places the number of places to round to.*/round : function(number, places, increment) {- 12
increment = increment || 1e-20;- 12
var factor = 10 / (10 * (increment || 10));- 12
return (Math.ceil(factor * +number) / factor).toFixed(places) * 1; // Number},/*** Rounds a number to the specified places, rounding up.** @example** comb.number.roundCeil(10.000001, 2); //10.01* comb.number.roundCeil(10.000002, 5); //10.00001* comb.number.roundCeil(10.0003, 3); //10.001* comb.number.roundCeil(10.0004, 2); //10.01* comb.number.roundCeil(10.0005, 3); //10.001* comb.number.roundCeil(10.0002, 2); //10.01** @param {Number} num the number to round.* @param {Number} places the number of places to round to.*/roundCeil : function(number, places){- 12
return Math.ceil(number * Math.pow(10, places))/Math.pow(10, places);}};
|
base/object.js
|
Coverage100.00
SLOC485
LOC139
Missed0
|
- 1
var comb = exports,misc = require("./misc.js"),isUndefinedOrNull = misc.isUndefined,isArguments = misc.isArguments,pSlice = Array.prototype.slice;//taken from node js assert.js//https://github.com/joyent/node/blob/master/lib/assert.js- 1
function _deepEqual(actual, expected) {// 7.1. All identical values are equivalent, as determined by ===.- 79
if (actual === expected) {- 6
return true;- 73
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {- 2
if (actual.length != expected.length) return false;- 2
for (var i = 0; i < actual.length; i++) {- 6
if (actual[i] !== expected[i]) return false;}- 2
return true;// 7.2. If the expected value is a Date object, the actual value is// equivalent if it is also a Date object that refers to the same time.- 71
} else if (actual instanceof Date && expected instanceof Date) {- 4
return actual.getTime() === expected.getTime();// 7.3 If the expected value is a RegExp object, the actual value is// equivalent if it is also a RegExp object with the same source and// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).- 67
} else if (actual instanceof RegExp && expected instanceof RegExp) {- 4
return actual.source === expected.source &&actual.global === expected.global &&actual.multiline === expected.multiline &&actual.lastIndex === expected.lastIndex &&actual.ignoreCase === expected.ignoreCase;// 7.4. Other pairs that do not both pass typeof value == 'object',// equivalence is determined by ==.- 63
} else if (typeof actual != 'object' && typeof expected != 'object') {- 23
return actual == expected;// 7.5 For all other Object pairs, including Array objects, equivalence is// determined by having the same number of owned properties (as verified// with Object.prototype.hasOwnProperty.call), the same set of keys// (although not necessarily the same order), equivalent values for every// corresponding key, and an identical 'prototype' property. Note: this// accounts for both named and indexed properties on Arrays.} else {- 40
return objEquiv(actual, expected);}}- 1
function objEquiv(a, b) {- 40
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))- 10
return false;// an identical 'prototype' property.- 30
if (a.prototype !== b.prototype) return false;//~~~I've managed to break Object.keys through screwy arguments passing.// Converting to array solves the problem.- 30
if (isArguments(a)) {- 4
if (!isArguments(b)) {- 2
return false;}- 2
a = pSlice.call(a);- 2
b = pSlice.call(b);- 2
return _deepEqual(a, b);}- 26
try {- 26
var ka = Object.keys(a),kb = Object.keys(b),key, i;} catch (e) {//happens when one is a string literal and the other isn't- 2
return false;}// having the same number of owned properties (keys incorporates// hasOwnProperty)- 24
if (ka.length != kb.length)- 4
return false;//the same set of keys (although not necessarily the same order),- 20
ka.sort();- 20
kb.sort();//~~~cheap key test- 20
for (i = ka.length - 1; i >= 0; i--) {- 20
if (ka[i] != kb[i])- 4
return false;}//equivalent values for every corresponding key, and//~~~possibly expensive deep test- 16
for (i = ka.length - 1; i >= 0; i--) {- 16
key = ka[i];- 22
if (!_deepEqual(a[key], b[key])) return false;}- 10
return true;}- 1
function merge(target, source) {- 467
var name, s;- 467
for (name in source) {- 644
s = source[name];- 644
if (!(name in target) || (target[name] !== s)) {- 642
target[name] = s;}}- 467
return target;}- 1
function deepMerge(target, source) {- 27
var name, s, t;- 27
for (name in source) {- 37
s = source[name], t = target[name];- 37
if (!_deepEqual(t, s)) {- 37
if (comb.isHash(t) && comb.isHash(s)) {- 8
target[name] = deepMerge(t, s);- 29
} else if (comb.isHash(s)) {- 8
target[name] = deepMerge({}, s);} else {- 21
target[name] = s;}}}- 27
return target;}/*** Determines if an object is just a hash and not a qualified Object such as Number** @example* comb.isHash({}) => true* comb.isHash({1 : 2, a : "b"}) => true* comb.isHash(new Date()) => false* comb.isHash(new String()) => false* comb.isHash(new Number()) => false* comb.isHash(new Boolean()) => false* comb.isHash() => false* comb.isHash("") => false* comb.isHash(1) => false* comb.isHash(false) => false* comb.isHash(true) => false* @param {Anything} obj the thing to test if it is a hash** @returns {Boolean} true if it is a hash false otherwise* @memberOf comb*/- 1
function isHash(obj) {- 271
var ret = comb.isObject(obj);- 271
return ret && obj.constructor === Object;}/*** Merges objects together* NOTE: this function takes a variable number of objects to merge** @example** var myObj = {};* comb.merge(myObj, {test : true});** myObj.test => true** comb.merge(myObj, {test : false}, {test2 : false}, {test3 : "hello", test4 : "world"});* myObj.test => false* myObj.test2 => false* myObj.test3 => "hello"* myObj.test4 => "world"*** @param {Object} obj the object to merge into* @param {Object} props variable number of objects to merge into the obj** @returns {Object} the merged object* @memberOf comb* @name merge*/- 1
function combMerge(obj, props) {- 442
if (!obj) {- 1
obj = {};}- 442
for (var i = 1, l = arguments.length; i < l; i++) {- 463
merge(obj, arguments[i]);}- 442
return obj; // Object}- 1
;/*** Merges objects together only overriding properties that are different.* NOTE: this function takes a variable number of objects to merge** @example** var myObj = {my : {cool : {property1 : 1, property2 : 2}}};* comb.deepMerge(myObj, {my : {cool : {property3 : 3}}});** myObj.my.cool.property1 => 1* myObj.my.cool.property2 => 2* myObj.my.cool.property3 => 3*** @param {Object} obj the object to merge into* @param {Object} props variable number of objects to merge into the obj** @returns {Object} the merged object* @memberOf comb* @name deepMerge*/- 1
function combDeepMerge(obj, props) {- 5
if (!obj) {- 1
obj = {};}- 5
for (var i = 1, l = arguments.length; i < l; i++) {- 11
deepMerge(obj, arguments[i]);}- 5
return obj; // Object}- 1
;/*** Extends the prototype of an object if it exists otherwise it extends the object.** @example** var MyObj = function(){};* MyObj.prototype.test = true;* comb.extend(MyObj, {test2 : false, test3 : "hello", test4 : "world"});** var myObj = new MyObj();** myObj.test => true* myObj.test2 => false* myObj.test3 => "hello"* myObj.test4 => "world"** var myObj2 = {};* myObj2.test = true;* comb.extend(myObj2, {test2 : false, test3 : "hello", test4 : "world"});** myObj2.test => true* myObj2.test2 => false* myObj2.test3 => "hello"* myObj2.test4 => "world"*** @param {Object} parent the parent object to extend* @param {Object} extend the extension object to mixin to the parent** @returns {Object} returns the extended object* @memberOf comb*/- 1
function extend(parent, extend) {- 4
var proto = parent.prototype || parent;- 4
merge(proto, extend);- 4
return parent;}/*** Determines if obj is an object** @param {Anything} obj the thing to test if it is an object** @returns {Boolean} true if it is an object false otherwise* @memberOf comb*/- 1
function isObject(obj) {- 1496
var undef;- 1496
return obj !== null && obj !== undef && typeof obj === "object";}/*** Determines if an object is empty** @example** comb.isEmpty({}) => true* comb.isEmpty({a : 1}) => false** @param object the object to test* @returns {Boolean} true if the object is empty;* @memberOf comb*/- 1
function isEmpty(object) {- 9
if (comb.isObject(object)) {- 8
for (var i in object) {- 4
if (object.hasOwnProperty(i)) {- 4
return false;}}}- 5
return true;}/*** Determines if two things are deep equal.** @example** comb.deepEqual({a : 1, b : 2}, {a : 1, b : 2}) => true* comb.deepEqual({a : 1}, {a : 1, b : 2}) => false** @param o1 the first thing to compare* @param o3 the second thing to compare* @return {Boolean}* @memberOf comb*/- 1
function deepEqual(o1, o2) {- 24
return _deepEqual(o1, o2);}- 1
comb.isHash = isHash;- 1
comb.isEmpty = isEmpty;- 1
comb.deepEqual = deepEqual;- 1
comb.isObject = isObject;- 1
comb.extend = extend;- 1
comb.deepMerge = combDeepMerge;- 1
comb.merge = combMerge;/*** Loops through each k/v in a hash.** ```* var obj = {a : "b", c : "d", e : "f"};* comb(obj).forEach(function(value, key){* console.log(value, key);* });** comb.hash.forEach(obj, function(){* console.log(value, key);* });** ```* @param {Object} hash the hash to iterate* @param {Function} iterator the interator function. Called with (key, value, hash).* @param {Object} [scope=hash] the scope to invoke the interator in.* @return {Object} the original hash.* @memberOf comb.hash*/- 1
function forEach(hash, iterator, scope) {- 6
if (!isHash(hash) || typeof iterator !== "function") {- 4
throw new TypeError();}- 2
var keys = Object.keys(hash), key;- 2
for (var i = 0, len = keys.length; i < len; ++i) {- 6
key = keys[i];- 6
iterator.call(scope || hash, hash[key], key, hash);}- 2
return hash;}/*** Filters out key/value pairs in an object. Filters out key/value pairs that return a falsey value from the iterator.** ```* var obj = {a : "b", c : "d", e : "f"};* comb(obj).filter(function(value, key){* return value == "b" || key === "e";* }); //{a : "b", e : "f"};** comb.hash.filter(obj, function(){* return value == "b" || key === "e";* }); //{a : "b", e : "f"};** ```* @param {Object} hash the hash to filter.* @param {Function} iterator the interator function. Called with (key, value, hash).* @param {Object} [scope=hash] the scope to invoke the interator in.* @return {Object} a new object with the values that returned true..* @memberOf comb.hash*/- 1
function filter(hash, iterator, scope) {- 6
if (!isHash(hash) || typeof iterator !== "function") {- 4
throw new TypeError();}- 2
var keys = Object.keys(hash), key, value, ret = {};- 2
for (var i = 0, len = keys.length; i < len; ++i) {- 6
key = keys[i];- 6
value = hash[key];- 6
if (iterator.call(scope || hash, value, key, hash)) {- 4
ret[key] = value;}}- 2
return ret;}/*** Returns the values of a hash.** ```* var obj = {a : "b", c : "d", e : "f"};* comb(obj).values(); //["b", "d", "f"]** comb.hash.values(obj); //["b", "d", "f"]** ```** @param {Object} hash the object to retrieve the values of.* @return {Array} array of values.* @memberOf comb.hash*/- 1
function values(hash) {- 5
if (!isHash(hash)) {- 3
throw new TypeError();}- 2
var keys = Object.keys(hash), ret = [];- 2
for (var i = 0, len = keys.length; i < len; ++i) {- 6
ret.push(hash[keys[i]]);}- 2
return ret;}/*** Returns a new hash that is the invert of the hash.** ```* var obj = {a : "b", c : "d", e : "f"};* comb(obj).invert(); //{b : "a", d : "c", f : "e"}** comb.hash.invert(obj); //{b : "a", d : "c", f : "e"}* ```** @param {Object} hash the hash to invert.* @return {Object} A new hash that is the invert of hash.* @memberOf comb.hash*/- 1
function invert(hash) {- 5
if (!isHash(hash)) {- 3
throw new TypeError();}- 2
var keys = Object.keys(hash), key, ret = {};- 2
for (var i = 0, len = keys.length; i < len; ++i) {- 6
key = keys[i];- 6
ret[hash[key]] = key;}- 2
return ret;}/*** Converts a hash to an array.** ```* var obj = {a : "b", c : "d", e : "f"};* comb(obj).toArray(); //[["a", "b"], ["c", "d"], ["e", "f"]]** comb.hash.toArray(obj); //[["a", "b"], ["c", "d"], ["e", "f"]]* ```** @param {Object} hash the hash to convert to an array.* @return {Array} a two dimensional array representing the hash.* @memberOf comb.hash*/- 1
function toArray(hash) {- 5
if (!isHash(hash)) {- 3
throw new TypeError();}- 2
var keys = Object.keys(hash), key, ret = [];- 2
for (var i = 0, len = keys.length; i < len; ++i) {- 6
key = keys[i];- 6
ret.push([key, hash[key]]);}- 2
return ret;}/*** @namespace utilities for working with hases i.e. {}* @ignoreCode*/- 1
comb.hash = {forEach:forEach,filter:filter,invert:invert,values:values,toArray:toArray};
|
base/regexp.js
|
Coverage100.00
SLOC48
LOC11
Missed0
|
- 1
var comb = exports;/*** Tests if something is a regular expression.** @example** comb.isRegExp(/hello/); //true* comb.isRegExp("hello"); //false** @param obj the thing to test.* @return {Boolean}* @static* @memberOf comb**/- 1
function isRegExp(obj) {- 13
var undef;- 13
return obj !== undef && obj != null && (obj instanceof RegExp);}- 1
comb.isRexExp = isRegExp;- 1
comb.isRegExp = isRegExp;/*** @namespace Regeular expression utilities**/- 1
comb.regexp = {/**@lends comb.regexp*//*** Escapes a string** @param {String} str the string to escape* @param {String} [except] characters to ignore** @returns {String} the escaped string*/escapeString:function (str, except) {- 46
return str.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function (ch) {- 46
if (except && except.indexOf(ch) != -1) {- 15
return ch;}- 31
return "\\" + ch;}); // String}};
|
base/string.js
|
Coverage100.00
SLOC1187
LOC131
Missed0
|
- 1
var comb = exports, date,misc = require("./misc"),object = require("./object"),isHash = object.isHash;/*** Tests if something is a string.** @example** comb.isString("true") //true* comb.isString(true) //false** @param obj the thing to test* @return {Boolean} returns true if the argument is a string.* @static* @memberOf comb*/- 1
function isString(obj) {- 36502
var undef;- 36502
return obj != undef && (typeof obj == "string" || obj instanceof String);}- 1
comb.isString = isString;- 1
var FORMAT_REGEX = /%((?:-?\+?.?\d*)?|(?:\[[^\[|\]]*\]))?([sjdDZ])/g;- 1
var INTERP_REGEX = /{(?:\[([^\[|\]]*)\])?(\w+)}/g;- 1
var STR_FORMAT = /(-?)(\+?)([A-Z|a-z|\W]?)([1-9][0-9]*)?$/;- 1
var OBJECT_FORMAT = /([1-9][0-9]*)$/g;- 1
var formatString = function (string, format) {- 64
var match = format.match(STR_FORMAT), ret = string, cString = comb.string;- 64
if (match) {- 64
var isLeftJustified = match[1], padChar = match[3], width = match[4];- 64
if (width) {- 64
width = parseInt(width);- 64
if (ret.length < width) {- 35
ret = cString.pad(ret, width, padChar, isLeftJustified);} else {- 29
ret = cString.truncate(ret, width);}}}- 64
return ret;};- 1
var formatNumber = function (number, format) {- 16
if (typeof number == "number") {- 14
var cString = comb.string, ret = "" + number;- 14
var match = format.match(STR_FORMAT);- 14
if (match) {- 14
var isLeftJustified = match[1], signed = match[2], padChar = match[3], width = match[4];- 14
if (signed) {- 6
ret = (number > 0 ? "+" : "") + ret;}- 14
if (width) {- 10
width = parseInt(width);- 10
if (ret.length < width) {- 8
ret = cString.pad(ret, width, padChar || "0", isLeftJustified);} else {- 2
ret = cString.truncate(ret, width);}}}} else {- 2
throw new Error("comb.string.format : when using %d the parameter must be a number!");}- 14
return ret;};- 1
var formatObject = function (object, format) {- 8
var ret, match = format.match(OBJECT_FORMAT), spacing = 0;- 8
if (match) {- 8
spacing = parseInt(match[0]);- 8
if (isNaN(spacing)) spacing = 0;}- 8
try {- 8
ret = JSON.stringify(object, null, spacing);} catch (e) {- 2
throw new Error("comb.string.format : Unable to parse json from ", object);}- 6
return ret;};- 1
var styles = {//stylesbold:1,bright:1,italic:3,underline:4,blink:5,inverse:7,crossedOut:9,red:31,green:32,yellow:33,blue:34,magenta:35,cyan:36,white:37,redBackground:41,greenBackground:42,yellowBackground:43,blueBackground:44,magentaBackground:45,cyanBackground:46,whiteBackground:47,encircled:52,overlined:53,grey:90,black:90};/**@namespace comb characters*/- 1
comb.characters = {/**@lends comb.characters*//*** âº*/SMILEY:"âº",/*** â»*/SOLID_SMILEY:"â»",/*** â¥*/HEART:"â¥",/*** â¦*/DIAMOND:"â¦",/*** â£*/CLOVE:"â£",/*** â*/SPADE:"â ",/*** â¢*/DOT:"â¢",/*** â*/SQUARE_CIRCLE:"â",/*** â*/CIRCLE:"â",/*** â*/FILLED_SQUARE_CIRCLE:"â",/*** â*/MALE:"â",/*** â*/FEMALE:"â",/*** âª*/EIGHT_NOTE:"âª",/*** â«*/DOUBLE_EIGHT_NOTE:"â«",/*** â¼*/SUN:"â¼",/*** âº*/PLAY:"âº",/*** â*/REWIND:"â",/*** â*/UP_DOWN:"â",/*** ¶*/PILCROW:"¶",/*** §*/SECTION:"§",/*** â¬*/THICK_MINUS:"â¬",/*** â¨*/SMALL_UP_DOWN:"â¨",/*** â*/UP_ARROW:"â",/*** â*/DOWN_ARROW:"â",/*** â*/RIGHT_ARROW:"â",/*** â*/LEFT_ARROW:"â",/*** â*/RIGHT_ANGLE:"â",/*** â*/LEFT_RIGHT_ARROW:"â",/*** â²*/TRIANGLE:"â²",/*** â¼*/DOWN_TRIANGLE:"â¼",/*** â*/HOUSE:"â",/*** Ã*/C_CEDILLA:"Ã",/*** ü*/U_UMLAUT:"ü",/*** é*/E_ACCENT:"é",/*** â*/A_LOWER_CIRCUMFLEX:"â",/*** ä*/A_LOWER_UMLAUT:"ä",/*** Ã*/A_LOWER_GRAVE_ACCENT:"à ",/*** Ã¥*/A_LOWER_CIRCLE_OVER:"Ã¥",/*** ç*/C_LOWER_CIRCUMFLEX:"ç",/*** ê*/E_LOWER_CIRCUMFLEX:"ê",/*** ë*/E_LOWER_UMLAUT:"ë",/*** è*/E_LOWER_GRAVE_ACCENT:"è",/*** ï*/I_LOWER_UMLAUT:"ï",/*** î*/I_LOWER_CIRCUMFLEX:"î",/*** ì*/I_LOWER_GRAVE_ACCENT:"ì",/*** Ã*/A_UPPER_UMLAUT:"Ã",/*** Ã*/A_UPPER_CIRCLE:"à ",/*** Ã*/E_UPPER_ACCENT:"Ã",/*** æ*/A_E_LOWER:"æ",/*** Ã*/A_E_UPPER:"Ã",/*** ô*/O_LOWER_CIRCUMFLEX:"ô",/*** ö*/O_LOWER_UMLAUT:"ö",/*** ò*/O_LOWER_GRAVE_ACCENT:"ò",/*** û*/U_LOWER_CIRCUMFLEX:"û",/*** ù*/U_LOWER_GRAVE_ACCENT:"ù",/*** ÿ*/Y_LOWER_UMLAUT:"ÿ",/*** Ã*/O_UPPER_UMLAUT:"Ã",/*** Ã*/U_UPPER_UMLAUT:"Ã",/*** ¢*/CENTS:"¢",/*** £*/POUND:"£",/*** Â¥*/YEN:"Â¥",/*** ¤*/CURRENCY:"¤",/*** â§*/PTS:"â§",/*** Æ*/FUNCTION:"Æ",/*** á*/A_LOWER_ACCENT:"á",/*** Ã*/I_LOWER_ACCENT:"Ã",/*** ó*/O_LOWER_ACCENT:"ó",/*** ú*/U_LOWER_ACCENT:"ú",/*** ñ*/N_LOWER_TILDE:"ñ",/*** Ã*/N_UPPER_TILDE:"Ã",/*** ª*/A_SUPER:"ª",/*** º*/O_SUPER:"º",/*** ¿*/UPSIDEDOWN_QUESTION:"¿",/*** â*/SIDEWAYS_L:"â",/*** ¬*/NEGATION:"¬",/*** ½*/ONE_HALF:"½",/*** ¼*/ONE_FOURTH:"¼",/*** ¡*/UPSIDEDOWN_EXCLAMATION:"¡",/*** «*/DOUBLE_LEFT:"«",/*** »*/DOUBLE_RIGHT:"»",/*** â*/LIGHT_SHADED_BOX:"â",/*** â*/MEDIUM_SHADED_BOX:"â",/*** â*/DARK_SHADED_BOX:"â",/*** â*/VERTICAL_LINE:"â",/*** â¤*/MAZE__SINGLE_RIGHT_T:"â¤",/*** â*/MAZE_SINGLE_RIGHT_TOP:"â",/*** â*/MAZE_SINGLE_RIGHT_BOTTOM_SMALL:"â",/*** â*/MAZE_SINGLE_LEFT_TOP_SMALL:"â",/*** â*/MAZE_SINGLE_LEFT_BOTTOM_SMALL:"â",/*** â*/MAZE_SINGLE_LEFT_T:"â",/*** â´*/MAZE_SINGLE_BOTTOM_T:"â´",/*** â¬*/MAZE_SINGLE_TOP_T:"â¬",/*** â¼*/MAZE_SINGLE_CENTER:"â¼",/*** â*/MAZE_SINGLE_HORIZONTAL_LINE:"â",/*** â¡*/MAZE_SINGLE_RIGHT_DOUBLECENTER_T:"â¡",/*** â*/MAZE_SINGLE_RIGHT_DOUBLE_BL:"â",/*** â¢*/MAZE_SINGLE_RIGHT_DOUBLE_T:"â¢",/*** â*/MAZE_SINGLE_RIGHT_DOUBLEBOTTOM_TOP:"â",/*** â*/MAZE_SINGLE_RIGHT_DOUBLELEFT_TOP:"â",/*** â*/MAZE_SINGLE_LEFT_DOUBLE_T:"â",/*** â§*/MAZE_SINGLE_BOTTOM_DOUBLE_T:"â§",/*** â¤*/MAZE_SINGLE_TOP_DOUBLE_T:"â¤",/*** â¥*/MAZE_SINGLE_TOP_DOUBLECENTER_T:"â¥",/*** â¨*/MAZE_SINGLE_BOTTOM_DOUBLECENTER_T:"â¨",/*** â*/MAZE_SINGLE_LEFT_DOUBLERIGHT_BOTTOM:"â",/*** â*/MAZE_SINGLE_LEFT_DOUBLERIGHT_TOP:"â",/*** â*/MAZE_SINGLE_LEFT_DOUBLEBOTTOM_TOP:"â",/*** â*/MAZE_SINGLE_LEFT_DOUBLETOP_BOTTOM:"â",/*** Î*/MAZE_SINGLE_LEFT_TOP:"Î",/*** â*/MAZE_SINGLE_RIGHT_BOTTOM:"â",/*** â*/MAZE_SINGLE_LEFT_CENTER:"â",/*** â«*/MAZE_SINGLE_DOUBLECENTER_CENTER:"â«",/*** âª*/MAZE_SINGLE_DOUBLECROSS_CENTER:"âª",/*** â£*/MAZE_DOUBLE_LEFT_CENTER:"â£",/*** â*/MAZE_DOUBLE_VERTICAL:"â",/*** â*/MAZE_DOUBLE_RIGHT_TOP:"â",/*** â*/MAZE_DOUBLE_RIGHT_BOTTOM:"â",/*** â*/MAZE_DOUBLE_LEFT_BOTTOM:"â",/*** â*/MAZE_DOUBLE_LEFT_TOP:"â",/*** â©*/MAZE_DOUBLE_BOTTOM_T:"â©",/*** â¦*/MAZE_DOUBLE_TOP_T:"â¦",/*** â*/MAZE_DOUBLE_LEFT_T:"â ",/*** â*/MAZE_DOUBLE_HORIZONTAL:"â",/*** â¬*/MAZE_DOUBLE_CROSS:"â¬",/*** â*/SOLID_RECTANGLE:"â",/*** â*/THICK_LEFT_VERTICAL:"â",/*** â*/THICK_RIGHT_VERTICAL:"â",/*** â*/SOLID_SMALL_RECTANGLE_BOTTOM:"â",/*** â*/SOLID_SMALL_RECTANGLE_TOP:"â",/*** Φ*/PHI_UPPER:"Φ",/*** â*/INFINITY:"â",/*** â©*/INTERSECTION:"â©",/*** â¡*/DEFINITION:"â¡",/*** ±*/PLUS_MINUS:"±",/*** â¥*/GT_EQ:"â¥",/*** â¤*/LT_EQ:"â¤",/*** â*/THEREFORE:"â ",/*** âµ*/SINCE:"âµ",/*** â*/DOESNOT_EXIST:"â",/*** â*/EXISTS:"â",/*** â*/FOR_ALL:"â",/*** â*/EXCLUSIVE_OR:"â",/*** â¡*/BECAUSE:"â¡",/*** ÷*/DIVIDE:"÷",/*** â*/APPROX:"â",/*** °*/DEGREE:"°",/*** â*/BOLD_DOT:"â",/*** ·*/DOT_SMALL:"·",/*** â*/CHECK:"â",/*** â*/ITALIC_X:"â",/*** â¿*/SUPER_N:"â¿",/*** ²*/SQUARED:"²",/*** ³*/CUBED:"³",/*** â*/SOLID_BOX:"â ",/*** â°*/PERMILE:"â°",/*** ®*/REGISTERED_TM:"®",/*** ©*/COPYRIGHT:"©",/*** â¢*/TRADEMARK:"â¢",/*** β*/BETA:"β",/*** γ*/GAMMA:"γ",/*** ζ*/ZETA:"ζ",/*** η*/ETA:"η",/*** ι*/IOTA:"ι",/*** κ*/KAPPA:"κ",/*** λ*/LAMBDA:"λ",/*** ν*/NU:"ν",/*** ξ*/XI:"ξ",/*** ο*/OMICRON:"ο",/*** Ï*/RHO:"Ï",/*** Ï*/UPSILON:"Ï ",/*** Ï*/CHI_LOWER:"Ï",/*** Ï*/CHI_UPPER:"Ï",/*** Ï*/PSI:"Ï",/*** α*/ALPHA:"α",/*** Ã*/ESZETT:"Ã",/*** Ï*/PI:"Ï",/*** Σ*/SIGMA_UPPER:"Σ",/*** Ï*/SIGMA_LOWER:"Ï",/*** µ*/MU:"µ",/*** Ï*/TAU:"Ï",/*** Î*/THETA:"Î",/*** Ω*/OMEGA:"Ω",/*** δ*/DELTA:"δ",/*** Ï*/PHI_LOWER:"Ï",/*** ε*/EPSILON:"ε"};/**@namespace String utilities*/- 1
comb.string = {/**@lends comb.string*//*** Pads a string** @example** comb.string.pad("STR", 5, " ", true) => "STR "* comb.string.pad("STR", 5, "$") => "$$STR"** @param {String} string the string to pad* @param {Number} length the length of the string when padded* @param {String} [ch= " "] character to pad the string with* @param {Boolean} [end=false] if true then the padding is added to the end** @returns {String} the padded string*/pad:function (string, length, ch, end) {- 349
string = "" + string; //check for numbers- 349
ch = ch || " ";- 349
var strLen = string.length;- 349
while (strLen < length) {- 231
if (end) {- 137
string += ch;} else {- 94
string = ch + string;}- 231
strLen++;}- 349
return string;},/*** Truncates a string to the specified length.* @example** //from the beginning* comb.string.truncate("abcdefg", 3) => "abc";* //from the end* comb.string.truncate("abcdefg", 3,true) => "efg"* //omit the length* comb.string.truncate("abcdefg") => "abcdefg"** @param {String} string the string to truncate* @param {Number} [length = -1] the max length of the string, if the string is* shorter than the length then the string is returned.* @param {Boolean} [end=false] truncate starting at the end of the string** @return {String} the truncated string.*/truncate:function (string, length, end) {- 45
var ret = string;- 45
if (comb.isString(ret)) {- 43
if (string.length > length) {- 27
if (end) {- 8
var l = string.length;- 8
ret = string.substring(l - length, l);} else {- 19
ret = string.substring(0, length);}}} else {- 2
ret = comb.string.truncate("" + ret, length);}- 45
return ret;},/*** Formats a string with the specified format** @example** var format = comb.string.format;** format("%s, %s", ["Hello", "World"]) => "Hello, World";* format("%[ 10]s, %[- 10]s", ["Hello", "World"])* => " Hello, World ";* format("%-!10s, %#10s, %10s and %-10s",* "apple", "orange", "bananas", "watermelons")* => "apple!!!!!, ####orange, bananas and watermelon"* format("%+d, %+d, %10d, %-10d, %-+#10d, %10d",* 1,-2, 1, 2, 3, 100000000000)* => "+1, -2, 0000000001, 2000000000, +3########, 1000000000"* format("%[h:mm a]D", [date]) => 7:32 PM - local -* format("%[h:mm a]Z", [date]) => 12:32 PM - UTC* //When using object formats they must be in an array otherwise* //format will try to interpolate the properties into the string.* format("%j", [{a : "b"}])* => '{"a":"b"}'* format("%1j, %4j", [{a : "b"}, {a : "b"}])* => '{\n "a": "b"\n},\n{\n "a": "b"\n}'* format("{hello}, {world}", {hello : "Hello", world : "World")* => "Hello, World";* format({[-s10]apple}, {[%#10]orange}, {[10]banana} and {[-10]watermelons}",* {* apple : "apple",* orange : "orange",* banana : "bananas",* watermelons : "watermelons"* });* => applesssss, ####orange, bananas and watermelon** @param {String} str the string to format, if you want to use a spacing character as padding (other than \\s) then put your format in brackets.* <ol>* <li>String Formats %[options]s</li>* <ul>* <li>- : left justified</li>* <li>Char : padding character <b>Excludes d,j,s</b></li>* <li>Number : width</li>* </ul>* </li>* <li>Number Formats %[options]d</li>* <ul>* <li>- : left justified</li>* <li>+ : signed number</li>* <li>Char : padding character <b>Excludes d,j,s</b></li>* <li>Number : width</li>* </ul>* </li>* <li>Object Formats %[options]j</li>* <ul>* <li>Number : spacing for object properties.</li>* </ul>* </li>* </ol>*** @param {Object|Array|Arguments...} obj the parameters to replace in the string* if an array is passed then the array is used sequentially* if an object is passed then the object keys are used* if a variable number of args are passed then they are used like an array** @returns {String} the formatted string*/format:function (str, obj) {- 112
!date && (date = require("./date"));- 112
if (obj instanceof Array) {- 48
var i = 0, len = obj.length;//find the matches- 48
return str.replace(FORMAT_REGEX, function (m, format, type) {- 88
var replacer, ret;- 88
if (i < len) {- 86
replacer = obj[i++];} else {//we are out of things to replace with so//just return the match?- 2
return m;}- 86
if (m == "%s" || m == "%d" || m == "%D") {//fast path!- 36
ret = replacer + "";- 50
} else if (m == "%Z") {- 2
ret = replacer.toUTCString();- 48
} else if (m == "%j") {- 4
try {- 4
ret = JSON.stringify(replacer);} catch (e) {- 2
throw new Error("comb.string.format : Unable to parse json from ", replacer);}} else {- 44
format = format.replace(/^\[|\]$/g, "");- 44
switch (type) {case "s":- 8
ret = formatString(replacer, format);- 8
break;case "d":- 14
ret = formatNumber(replacer, format);- 12
break;case "j":- 6
ret = formatObject(replacer, format);- 4
break;case "D":- 8
ret = date.date.format(replacer, format);- 8
break;case "Z":- 8
ret = date.date.format(replacer, format, true);- 8
break;}}- 80
return ret;});- 64
} else if (isHash(obj)) {- 36
return str.replace(INTERP_REGEX, function (m, format, value) {- 142
value = obj[value];- 142
if (!misc.isUndefined(value)) {- 140
if (format) {- 86
if (comb.isString(value)) {- 56
return formatString(value, format);- 30
} else if (typeof value == "number") {- 2
return formatNumber(value, format);- 28
} else if (date.isDate(value)) {- 26
return date.date.format(value, format);- 2
} else if (typeof value == "object") {- 2
return formatObject(value, format);}} else {- 54
return "" + value;}}- 2
return m;});} else {- 28
var args = Array.prototype.slice.call(arguments).slice(1);- 28
return exports.string.format(str, args);}},/*** Converts a string to an array** @example** comb.string.toArray("a|b|c|d", "|") => ["a","b","c","d"]* comb.string.toArray("a", "|") => ["a"]* comb.string.toArray("", "|") => []** @param {String} str the string to parse* @param {String} delimeter the delimeter to use*/toArray:function (testStr, delim) {- 6
var ret = [];- 6
if (testStr) {- 6
if (testStr.indexOf(delim) > 0) return testStr.replace(/\s+/g, "").split(delim);- 2
else return [testStr];}- 2
return ret;},/*** Returns a string duplicated n times;** @example** comb.string.multiply("HELLO", 5) => "HELLOHELLOHELLOHELLOHELLO"***/multiply:function (str, times) {- 156
var ret = [];- 156
if (times) {- 150
for (var i = 0; i < times; i++) {- 568
ret.push(str);}}- 156
return ret.join("");},/*** Styles a string according to the specified styles.** @example* //style a string red* comb.string.style('myStr', 'red');* //style a string red and bold* comb.string.style('myStr', ['red', bold]);** @param {String} str The string to style.* @param {String|Array} styles the style or styles to apply to a string.* options include :* <ul>* <li>bold</li>* <li>bright</li>* <li>italic</li>* <li>underline</li>* <li>inverse</li>* <li>crossedOut</li>* <li>blink</li>* <li>red</li>* <li>green</li>* <li>yellow</li>* <li>blue</li>* <li>magenta</li>* <li>cyan</li>* <li>white</li>* <li>redBackground</li>* <li>greenBackground</li>* <li>yellowBackground</li>* <li>blueBackground</li>* <li>magentaBackground</li>* <li>cyanBackground</li>* <li>whiteBackground</li>* <li>grey</li>* <li>black</li>** </ul>*/style:function (str, options) {- 89
var ret = str;- 89
if (options) {- 89
if (ret instanceof Array) {- 2
ret = ret.map(function (s) {- 6
return comb.string.style(s, options);})- 87
} else if (options instanceof Array) {- 8
options.forEach(function (option) {- 24
ret = comb.string.style(ret, option);});- 79
} else if (options in styles) {- 79
ret = '\x1B[' + styles[options] + 'm' + str + '\x1B[0m';}}- 89
return ret;}};
|
collections/AVLTree.js
|
Coverage100.00
SLOC203
LOC100
Missed0
|
- 1
var define = require("../define").define,Tree = require("./Tree"),base = require("../base"),multiply = base.string.multiply;- 1
var abs = Math.abs;- 1
var makeNode = function(data) {- 122
return {data : data,balance : 0,left : null,right : null}};- 1
var rotateSingle = function(root, dir, otherDir) {- 80
var save = root[otherDir];- 80
root[otherDir] = save[dir];- 80
save[dir] = root;- 80
return save;};- 1
var rotateDouble = function(root, dir, otherDir) {- 15
root[otherDir] = rotateSingle(root[otherDir], otherDir, dir);- 15
return rotateSingle(root, dir, otherDir);};- 1
var adjustBalance = function(root, dir, bal) {- 15
var otherDir = dir == "left" ? "right" : "left";- 15
var n = root[dir], nn = n[otherDir];- 15
if (nn.balance == 0)- 11
root.balance = n.balance = 0;- 4
else if (nn.balance == bal) {- 2
root.balance = -bal;- 2
n.balance = 0;}else { /* nn.balance == -bal */- 2
root.balance = 0;- 2
n.balance = bal;}- 15
nn.balance = 0;};- 1
var insertAdjustBalance = function(root, dir) {- 60
var otherDir = dir == "left" ? "right" : "left";- 60
var n = root[dir];- 60
var bal = dir == "left" ? -1 : +1;- 60
if (n.balance == bal) {- 46
root.balance = n.balance = 0;- 46
root = rotateSingle(root, otherDir, dir);}else {- 14
adjustBalance(root, dir, bal);- 14
root = rotateDouble(root, otherDir, dir);}- 60
return root;};- 1
var removeAdjustBalance = function(root, dir, done) {- 5
var otherDir = dir == "left" ? "right" : "left";- 5
var n = root[otherDir];- 5
var bal = dir == "left" ? -1 : 1;- 5
if (n.balance == -bal) {- 1
root.balance = n.balance = 0;- 1
root = rotateSingle(root, dir, otherDir);}- 4
else if (n.balance == bal) {- 1
adjustBalance(root, otherDir, -bal);- 1
root = rotateDouble(root, dir, otherDir);}else { /* n.balance == 0 */- 3
root.balance = -bal;- 3
n.balance = bal;- 3
root = rotateSingle(root, dir, otherDir);- 3
done.done = true;}- 5
return root;};- 1
var insert = function(root, data, done, compare) {- 472
if (root == null || root == undefined)- 122
root = makeNode(data);else {- 350
var dir = compare(data, root.data) == -1 ? "left" : "right";- 350
root[dir] = insert(root[dir], data, done, compare);- 350
if (!done.done) {/* Update balance factors */- 255
root.balance += dir == "left" ? -1 : 1;/* Rebalance as necessary and terminate */- 255
if (root.balance == 0)- 21
done.done = true;- 234
else if (abs(root.balance) > 1) {- 60
root = insertAdjustBalance(root, dir);- 60
done.done = true;}}}- 472
return root;};- 1
var remove = function(root, data, done, compare) {- 57
var dir, cmp, save, b;- 57
if (root) {//Remove node- 57
cmp = compare(data, root.data);- 57
if (cmp === 0) {// Unlink and fix parent- 26
var l = root.left, r = root.right;- 26
if (!l || !r) {- 18
dir = !l ? "right" : "left";- 18
save = root[dir];- 18
return save;}else {- 8
var heir = l, r;- 8
while ((r = heir.right) != null) {- 3
heir = r;}- 8
root.data = heir.data;//reset and start searching- 8
data = heir.data;}}- 39
dir = compare(root.data, data) == -1 ? "right" : "left";- 39
root[dir] = remove(root[dir], data, done, compare);- 39
if (!done.done) {/* Update balance factors */- 24
b = (root.balance += (dir == "left" ? 1 : -1));/* Terminate or rebalance as necessary */- 24
var a = abs(b);- 24
if (a === 1)- 10
done.done = true;- 14
else if (a > 1)- 5
root = removeAdjustBalance(root, dir, done);}}- 39
return root;};/*** @ignoreCode* @class <p>An AVL tree is a self-balancing binary search tree.* In an AVL tree, the heights of the two child subtrees of any node differ by at most one.* Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases,* where n is the number of nodes in the tree prior to the operation.* Insertions and deletions may require the tree to be rebalanced by one or more tree rotations.</p>* <p>AVL trees are more rigidly balanced than red-black trees, leading to slower insertion and removal but faster retrieval</p>** <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>Space</td><td>O(n)</td><td>O(n)</td></tr>* <tr><td>Search</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Delete</td><td>O(log n)</td><td>O(log n)</td></tr>* <table>* @name AVLTree* @augments comb.collections.Tree* @memberOf comb.collections*/- 1
module.exports = exports = define(Tree, {instance : {/**@lends comb.collections.AVLTree.prototype*/insert : function(data) {- 122
var done = {done : false};- 122
this.__root = insert(this.__root, data, done, this.compare);},remove : function(data) {- 18
this.__root = remove(this.__root, data, {done : false}, this.compare);},__printNode : function(node, level) {- 37
var str = [];- 37
if (node == null) {- 19
str.push(multiply('\t', level));- 19
str.push("~");- 19
console.log(str.join(""));} else {- 18
this.__printNode(node.right, level + 1);- 18
str.push(multiply('\t', level));- 18
str.push(node.data + ":" + node.balance + "\n");- 18
console.log(str.join(""));- 18
this.__printNode(node.left, level + 1);}}}});
|
collections/AnderssonTree.js
|
Coverage100.00
SLOC165
LOC76
Missed0
|
- 1
var define = require("../define").define,Tree = require("./Tree"),base = require("../base"),multiply = base.string.multiply;- 1
var RED = "red", BLACK = "black";- 1
var nil = {level:0, data:null};- 1
var makeNode = function (data, level) {- 122
return {data:data,level:level,left:nil,right:nil}};- 1
var skew = function (root) {- 384
if (root.level != 0 && root.left.level == root.level) {- 66
var save = root.left;- 66
root.left = save.right;- 66
save.right = root;- 66
root = save;}- 384
return root;};- 1
var split = function (root) {- 384
if (root.level != 0 && root.right.right.level == root.level) {- 79
var save = root.right;- 79
root.right = save.left;- 79
save.left = root;- 79
root = save;- 79
++root.level;}- 384
return root;};- 1
var insert = function (root, data, compare) {- 492
if (root == nil) {- 122
root = makeNode(data, 1);}else {- 370
var dir = compare(data, root.data) == -1 ? "left" : "right";- 370
root[dir] = insert(root[dir], data, compare);- 370
root = skew(root);- 370
root = split(root);}- 492
return root;};- 1
var remove = function (root, data, compare) {- 59
var rLeft, rRight;- 59
if (root != nil) {- 59
var cmp = compare(data, root.data);- 59
if (cmp == 0) {- 26
rLeft = root.left, rRight = root.right;- 26
if (rLeft != nil && rRight != nil) {- 8
var heir = rLeft;- 8
while (heir.right != nil)- 3
heir = heir.right;- 8
root.data = heir.data;- 8
root.left = remove(rLeft, heir.data, compare);} else {- 18
root = root[rLeft == nil ? "right" : "left"];}} else {- 33
var dir = cmp == -1 ? "left" : "right";- 33
root[dir] = remove(root[dir], data, compare);}}- 59
if (root != nil) {- 42
var rLevel = root.level;- 42
var rLeftLevel = root.left.level, rRightLevel = root.right.level;- 42
if (rLeftLevel < rLevel - 1 || rRightLevel < rLevel - 1) {- 14
if (rRightLevel > --root.level)- 2
root.right.level = root.level;- 14
root = skew(root);- 14
root = split(root);}}- 59
return root;};/**** @ignoreCode* @class <p>Andersson Trees are a version of a balanced Binary tree, while similar to RedBlack Trees the balancing is not as strict.</p>** <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>space</td><td>O(n)</td><td>O(n)</td></tr>* <tr><td>Search</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Delete</td><td>O(log n)</td><td>O(log n)</td></tr>* <table>* @name AnderssonTree* @augments comb.collections.Tree* @memberOf comb.collections*/- 1
module.exports = exports = define(Tree, {instance:{/**@lends comb.collections.AnderssonTree.prototype*/isEmpty:function () {- 4
return this.__root == nil || this._super(arguments);},insert:function (data) {- 130
if (this.__root == null) this.__root = nil;- 122
this.__root = insert(this.__root, data, this.compare);},remove:function (data) {- 18
this.__root = remove(this.__root, data, this.compare);},traverseWithCondition:function (node, order, callback) {- 614
var cont = true;- 614
if (node != nil) {- 317
return this._super(arguments);}- 297
return cont;},traverse:function (node, order, callback) {- 989
if (node != nil) {- 482
this._super(arguments);}},contains:function (value) {- 44
if (this.__root != nil) {- 26
return this._super(arguments);}- 18
return false;},__printNode:function (node, level) {- 37
var str = [];- 37
if (node.data == null || node == null) {- 19
str.push(multiply('\t', level));- 19
str.push("~");- 19
console.log(str.join(""));} else {- 18
this.__printNode(node.right, level + 1);- 18
str.push(multiply('\t', level));- 18
str.push(node.data + ":" + node.level + "\n");- 18
console.log(str.join(""));- 18
this.__printNode(node.left, level + 1);}}}});
|
collections/BinaryTree.js
|
Coverage100.00
SLOC83
LOC30
Missed0
|
- 1
var define = require("../define").define,Tree = require("./Tree"),base = require("../base");/**** @ignoreCode* @class <p>A Search tree that maintains the following properties</p>* <ul>* <li>The left subtree of a node contains only nodes with keys less than the node's key.* <li>The right subtree of a node contains only nodes with keys greater than the node's key.* <li>Both the left and right subtrees must also be binary search trees.* </ul>** <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>Space</td><td>O(n)</td><td>O(n)</td></tr>* <tr><td>Search</td><td>O(log n)</td><td>O(n)</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(n)</td></tr>* <tr><td>Delete</td><td>O(log n)</td><td>O(n)</td></tr>* <table>* @name BinaryTree* @augments comb.collections.Tree* @memberOf comb.collections*/- 1
module.exports = exports = define(Tree, {instance : {/**@lends comb.collections.BinaryTree.prototype*/insert : function(data) {- 124
if (this.__root == null) {- 9
return (this.__root = {data : data,parent : null,left : null,right : null});}- 115
var compare = this.compare;- 115
var root = this.__root;- 115
while (root != null) {- 505
var cmp = compare(data, root.data);- 505
if (cmp) {- 503
var leaf = (cmp == -1) ? "left" : "right";- 503
var next = root[leaf];- 503
if (next == null) {- 113
return (root[leaf] = {data : data, parent : root, left : null, right : null});} else {- 390
root = next;}} else {- 2
return;}}},remove : function(data) {- 19
if (this.__root != null) {- 19
var head = {right : this.__root}, it = head;- 19
var p, f = null;- 19
var dir = "right";- 19
while (it[dir] != null) {- 51
p = it;- 51
it = it[dir];- 51
var cmp = this.compare(data, it.data);- 51
if (!cmp) {- 18
f = it;}- 51
dir = (cmp == -1 ? "left" : "right");}- 19
if (f != null) {- 18
f.data = it.data;- 18
p[p.right == it ? "right" : "left"] = it[it.left == null ? "right" : "left"];}- 19
this.__root = head.right;}}}});
|
collections/Collection.js
|
Coverage100.00
SLOC56
LOC8
Missed0
|
- 1
var define = require("../define").define,base = require("../base");/*** @ignoreCode* @class Base class for all collections* @name Collection* @memberOf comb.collections*/- 1
define(null, {instance:{/**@lends comb.collections.Collection.prototype*//*** Concats two collections*/concat:function () {- 1
throw new Error("Not Implemented");},/*** Joins two collections*/join:function () {- 1
throw new Error("Not Implemented");},/*** Slice a portion from a collection*/slice:function () {- 1
throw new Error("Not Implemented");},/*** Convert a collection to a string*/toString:function () {- 1
throw new Error("Not Implemented");},/*** Find the index of an item in a collection*/indexOf:function () {- 1
throw new Error("Not Implemented");},/*** Find the last index of an item in a collection*/lastIndexOf:function () {- 1
throw new Error("Not Implemented");}}}).as(module);
|
collections/HashTable.js
|
Coverage100.00
SLOC378
LOC126
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),Iterable = require("./Iterable"),base = require("../base");- 1
var hashFunction = function (key) {- 100
if (typeof key == "string") {- 26
return key;- 74
} else if (typeof key == "object") {- 44
return key.hashCode ? key.hashCode() : "" + key;} else {- 30
return "" + key;}};- 1
var Bucket = define(null, {instance:{constructor:function () {- 32
this.__entries = [];},pushValue:function (key, value) {- 36
this.__entries.push({key:key, value:value});- 36
return value;},remove:function (key) {- 14
var ret = null, map = this.__entries, val;- 14
var i = map.length - 1;- 14
for (; i >= 0; i--) {- 16
if ((val = map[i]) != null && val.key === key) {- 12
map[i] = null;- 12
return val.value;}}- 2
return ret;},"set":function (key, value) {- 14
var ret = null, map = this.__entries;- 14
var i = map.length - 1;- 14
for (; i >= 0; i--) {- 18
var val = map[i];- 18
if (val && key === val.key) {- 6
val.value = value;- 6
ret = value;- 6
break;}}- 14
if (!ret) {- 8
map.push({key:key, value:value});}- 14
return ret;},find:function (key) {- 34
var ret = null, map = this.__entries, val;- 34
var i = map.length - 1;- 34
for (; i >= 0; i--) {- 43
val = map[i];- 43
if (val && key === val.key) {- 26
ret = val.value;- 26
break;}}- 34
return ret;},getEntrySet:function (arr) {- 78
var map = this.__entries, l = map.length;- 78
if (l) {- 78
for (var i = 0; i < l; i++) {- 88
var e = map[i];- 88
if (e) {- 80
arr.push(e);}}}},getKeys:function (arr) {- 21
var map = this.__entries, l = map.length;- 21
if (l) {- 21
for (var i = 0; i < l; i++) {- 24
var e = map[i];- 24
if (e) {- 8
arr.push(e.key);}}}- 21
return arr;},getValues:function (arr) {- 14
var map = this.__entries, l = map.length;- 14
if (l) {- 14
for (var i = 0; i < l; i++) {- 16
var e = map[i];- 16
if (e) {- 8
arr.push(e.value);}}}- 14
return arr;}}});/*** @ignoreCode* @class <p>Implementation of a HashTable for javascript.* This HashTable implementation allows one to use anything as a key.* </p>* <b>NOTE: THIS IS ~ 3 times slower than javascript native objects</b>** <p> A use case for this collection is when one needs to store items in which the key will not be a string, or number</p>** @name HashTable* @augments comb.collections.Collection* @memberOf comb.collections** @property {Array} keys all keys contained in the table* @property {Array} values all values contained in the table* @property {Array} entrySet an array of objects. Each object contains a key, and value property.*/- 1
define([Collection, Iterable], {instance:{/**@lends comb.collections.HashTable.prototype*/constructor:function () {- 13
this.__map = {};},__entrySet:function () {- 14
var ret = [], es = [];- 14
for (var i in this.__map) {- 78
this.__map[i].getEntrySet(ret);}- 14
return ret;},/*** Put a key, value pair into the table** <b>NOTE :</b> the collection will not check if the key previously existed.** @param {Anything} key the key to look up the object.* @param {Anything} value the value that corresponds to the key.** @returns the value*/put:function (key, value) {- 29
var hash = hashFunction(key);- 29
var bucket = null;- 29
if ((bucket = this.__map[hash]) == null) {- 25
bucket = (this.__map[hash] = new Bucket());}- 29
bucket.pushValue(key, value);- 29
return value;},/*** Remove a key value pair from the table.** @param key the key of the key value pair to remove.** @returns the removed value.*/remove:function (key) {- 16
var hash = hashFunction(key), ret = null;- 16
var bucket = this.__map[hash];- 16
if (bucket) {- 14
ret = bucket.remove(key);}- 16
return ret;},/*** Get the value corresponding to the key.** @param key the key used to look up the value** @returns null if not found, or the value.*/"get":function (key) {- 26
var hash = hashFunction(key), ret = null;- 26
var bucket = null;- 26
if ((bucket = this.__map[hash]) != null) {- 26
ret = bucket.find(key);}- 26
return ret;},/*** Set the value of a previously existing key,value pair or create a new entry.** @param key the key to be be used* @param value the value to be set** @returns the value.*/"set":function (key, value) {- 21
var hash = hashFunction(key), ret = null, bucket = null, map = this.__map;- 21
if ((bucket = map[hash]) != null) {- 14
ret = bucket.set(key, value);} else {- 7
ret = (map[hash] = new Bucket()).pushValue(key, value);}- 21
return ret;},/*** Tests if the table contains a particular key* @param key the key to test** @returns {Boolean} true if it exitsts false otherwise.*/contains:function (key) {- 8
var hash = hashFunction(key), ret = false;- 8
var bucket = null;- 8
if ((bucket = this.__map[hash]) != null) {- 8
ret = bucket.find(key) != null;}- 8
return ret;},/*** Returns a new HashTable containing the values of this HashTable, and the other table.* </br>* <b> DOES NOT CHANGE THE ORIGINAL!</b>* @param {comb.collections.HashTable} hashTable the hash table to concat with this.** @returns {comb.collections.HashTable} a new HashTable containing all values from both tables.*/concat:function (hashTable) {- 2
if (hashTable instanceof this._static) {- 1
var ret = new this._static();- 1
var otherEntrySet = hashTable.entrySet.concat(this.entrySet);- 1
for (var i = otherEntrySet.length - 1; i >= 0; i--) {- 4
var e = otherEntrySet[i];- 4
ret.put(e.key, e.value);}- 1
return ret;} else {- 1
throw new TypeError("When joining hashtables the joining arg must be a HashTable");}},/*** Creates a new HashTable containg values that passed the filtering function.** @param {Function} cb Function to callback with each item, the first aruguments is an object containing a key and value field* @param {Object} scope the scope to call the function.** @returns {comb.collections.HashTable} the HashTable containing the values that passed the filter.*/filter:function (cb, scope) {- 1
var es = this.__entrySet(), ret = new this._static();- 1
es = es.filter.apply(es, arguments);- 1
for (var i = es.length - 1; i >= 0; i--) {- 4
var e = es[i];- 4
ret.put(e.key, e.value);}- 1
return ret;},/*** Loop through each value in the hashtable** @param {Function} cb the function to call with an object containing a key and value field* @param {Object} scope the scope to call the funciton in*/forEach:function (cb, scope) {- 1
var es = this.__entrySet(), l = es.length, f = cb.bind(scope || this);- 1
es.forEach.apply(es, arguments);},/*** Determines if every item meets the condition returned by the callback.** @param {Function} cb Function to callback with each item, the first aruguments is an object containing a key and value field* @param {Object} [scope=this] scope to call the function in** @returns {Boolean} True if every item passed false otherwise*/every:function () {- 2
var es = this.__entrySet();- 2
return es.every.apply(es, arguments);},/*** Loop through each value in the hashtable, collecting the value returned by the callback function.* @param {Function} cb Function to callback with each item, the first aruguments is an object containing a key and value field* @param {Object} [scope=this] scope to call the function in** @returns {Array} an array containing the mapped values.*/map:function () {- 1
var es = this.__entrySet(), ret = new this._static();- 1
return es.map.apply(es, arguments);},/*** Determines if some items meet the condition returned by the callback.** @param {Function} cb Function to callback with each item, the first aruguments is an object containing a key and value field* @param {Object} [scope=this] scope to call the function in** @returns {Boolean} True if some items passed false otherwise*/some:function () {- 2
var es = this.__entrySet();- 2
return es.some.apply(es, arguments);},/*** Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value.** @param {Function} callback Function to execute on each value in the array.* @param initialValue Value to use as the first argument to the first call of the callback..*/reduce:function () {- 1
var es = this.__entrySet();- 1
return es.reduce.apply(es, arguments);},/*** Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value.** @param {Function} callback Function to execute on each value in the array.* @param initialValue Value to use as the first argument to the first call of the callback..*/reduceRight:function () {- 1
var es = this.__entrySet();- 1
return es.reduceRight.apply(es, arguments);},/*** Clears out all items from the table.*/clear:function () {- 1
this.__map = {};},getters:{keys:function () {- 8
var ret = [], es = [];- 8
for (var i in this.__map) {- 21
this.__map[i].getKeys(ret);}- 8
return ret;},values:function () {- 6
var ret = [], es = [];- 6
for (var i in this.__map) {- 14
this.__map[i].getValues(ret);}- 6
return ret;},entrySet:function () {- 5
return this.__entrySet();},isEmpty:function () {- 2
return this.keys.length == 0;}}}}).as(module);
|
collections/Heap.js
|
Coverage100.00
SLOC218
LOC62
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),base = require("../base");- 1
var padding = function(char, numSpaces) {- 9
var ret = [];- 9
for (var i = 0; i < numSpaces; i++)- 16
ret.push(char);- 9
return ret.join("");};- 1
module.exports = exports = define(Collection, {instance : {/**@lends comb.collections.Heap.prototype*/__getParentIndex : function(index) {- 192
return Math.floor((index - 1) / 2);},__getLeftChildIndex : function(index) {- 28
return (index * 2) + 1;},__getRightChildIndex : function(index) {- 28
return (index * 2) + 2;},__makeNode : function(key, value) {- 137
return {key : key, value : value};},/*** Base class for Heap Implementations.*** @constructs* @augments comb.collections.Collection* @memberOf comb.collections** @property {Number} count the current number of elements.* @property {Array} keys the keys of all items in the heap.* @property {Array} values the values contained in the heap.* @property {Boolean} isEmpty true if the Heap is empty.*/constructor : function() {- 32
this.__heap = [];},/*** Insert a key value into the key* @param key* @param value*/insert : function(key, value) {- 138
if (!base.isString(key)) {- 137
var l = this.__heap.push(this.__makeNode(key, value));- 137
this.__upHeap(l - 1);} else {- 1
throw TypeError("Invalid key");}},/*** Removes the root from the heap** @returns the value of the root*/remove : function() {- 48
var ret = undefined, heap = this.__heap, l = heap.length;- 48
if (l) {- 48
ret = heap[0];- 48
if (l == 1) {- 12
heap.length = 0;} else {- 36
heap[0] = heap.pop();- 36
this.__downHeap(0);}}- 48
return ret ? ret.value : ret;},/*** Gets he value of the root node with out removing it.** @returns the value of the root*/peek : function() {- 33
var ret = undefined, heap = this.__heap, l = heap.length;- 33
if (l) {- 30
ret = heap[0];}- 33
return ret ? ret.value : ret;},/*** Gets the key of the root node without removing it.** @returns the key of the root*/peekKey : function() {- 6
var ret = undefined, heap = this.__heap, l = heap.length;- 6
if (l) {- 4
ret = heap[0];}- 6
return ret ? ret.key : ret;},/*** Perform the heapify operation after the an* item as been added to the bottom of the heap.** @param index the index in which the new item was added*/__upHeap : function(index) {- 1
throw Error("NOT IMPLEMENTED");},/*** Heapify the heap after the root has been removed** @param index the index of the root*/__downHeap : function(index) {- 1
throw Error("NOT IMPLEMENTED");},/**** Determine if the heap contains a particular key.** @param key key to test.** @returns {Boolean} true if the key is contained in this heap.*/containsKey : function(key) {- 15
var heap = this.__heap;- 15
for (var i = heap.length - 1; i >= 0; i--) {- 42
if (heap[i].key == key) {- 12
return true;}}- 3
return false;},/**** Determine if the heap contains a particular value.** @param value value to test.** @returns {Boolean} true if the value is contained in this heap.*/containsValue : function(value) {- 15
var heap = this.__heap;- 15
for (var i = heap.length - 1; i >= 0; i--) {- 42
if (heap[i].value == value) {- 12
return true;}}- 3
return false;},/*** Empty the heap.*/clear : function() {- 9
this.__heap.length = 0;},__printNode : function(index, level) {//console.log(level);- 9
var str = [], node = this.__heap[index];- 9
if (node == null || node == undefined) {- 5
str.push(padding('\t', level));- 5
str.push("~");- 5
console.log(str.join(""));} else {- 4
this.__printNode(this.__getRightChildIndex(index), level + 1);- 4
str.push(padding('\t', level));- 4
str.push(node.key + " : " + node.value + "\n");- 4
console.log(str.join(""));- 4
this.__printNode(this.__getLeftChildIndex(index), level + 1);}},/*** Print the heap.*/print : function() {- 1
this.__printNode(0, 0);},getters : {count : function() {- 12
return this.__heap.length;},keys : function() {- 3
return this.__heap.map(function(n) {- 12
return n.key;});},values : function() {- 3
return this.__heap.map(function(n) {- 12
return n.value;});},isEmpty : function() {- 18
return this.__heap.length == 0;}}}});
|
collections/Iterable.js
|
Coverage100.00
SLOC63
LOC9
Missed0
|
- 1
var define = require("../define").define,base = require("../base");/*** @ignoreCode* @class Base class for all collections* @name Iterable* @memberOf comb.collections*/- 1
define(null, {instance:{/**@lends comb.collections.Iterable.prototype*//*** Filter items from a collection*/filter:function () {- 1
throw new Error("Not Implemented");},/*** Loop through the items in a collection*/forEach:function () {- 1
throw new Error("Not Implemented");},/*** Determine if every item in a collection meets the criteria*/every:function () {- 1
throw new Error("Not Implemented");},/*** Map every item in a collection*/map:function () {- 1
throw new Error("Not Implemented");},/*** Determing if some items in a colleciton meet the criteria*/some:function () {- 1
throw new Error("Not Implemented");},/*** Reduce a collection*/reduce:function () {- 1
throw new Error("Not Implemented");},/*** Reduce a collection starting from the right most position*/reduceRight:function () {- 1
throw new Error("Not Implemented");}}}).as(module);
|
collections/MaxHeap.js
|
Coverage100.00
SLOC66
LOC25
Missed0
|
- 1
var define = require("../define").define,Heap = require("./Heap"),base = require("../base");/*** @ignoreCode** @class <p> Max Heap implementation, lowest value in heap is always at the root.</p>* </br>* <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Remove</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Peek</td><td>O(1)</td><td>O(1)</td></tr>* <tr><td>Contains</td><td>O(n)</td><td>O(n)</td></tr>* <table>* @name MaxHeap* @augments comb.collections.Heap* @memberOf comb.collections*/- 1
exports = module.exports = define(Heap, {instance : {__upHeap : function(index) {- 48
var heap = this.__heap;- 48
var node = heap[index];- 48
while (index >= 0) {- 84
var parentIndex = this.__getParentIndex(index), parent = heap[parentIndex];- 84
if (parent && parent.key < node.key) {- 36
heap[index] = parent;- 36
index = parentIndex;} else {- 48
break;}}- 48
heap[index] = node;},__downHeap : function(index) {- 12
var heap = this.__heap;- 12
var node = heap[index], length = heap.length;- 12
while (index < Math.floor(length / 2)) {- 8
var leftIndex = this.__getLeftChildIndex(index),rightIndex = this.__getRightChildIndex(index), left = heap[leftIndex], right = heap[rightIndex], child, childIndex;- 8
if (rightIndex < length && right.key < left.key) {- 4
childIndex = leftIndex;- 4
child = left} else {- 4
childIndex = leftIndex;- 4
child = heap[leftIndex];}- 8
if(child.key > node.key){- 5
heap[index] = child;- 5
index = childIndex;}else{- 3
break;}}- 12
heap[index] = node;}}});
|
collections/MinHeap.js
|
Coverage100.00
SLOC65
LOC26
Missed0
|
- 1
var define = require("../define").define,Heap = require("./Heap"),base = require("../base");- 1
var floor = Math.floor, MinHeap;/*** @class <p> Min Heap implementation, lowest value in heap is always at the root.</p>* </br>* <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Remove</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Peek</td><td>O(1)</td><td>O(1)</td></tr>* <tr><td>Contains</td><td>O(n)</td><td>O(n)</td></tr>* <table>* @name MinHeap* @augments comb.collections.Heap* @memberOf comb.collections* @ignoreCode*/- 1
module.exports = exports = define(Heap, {instance : {__upHeap : function(index) {- 88
var heap = this.__heap;- 88
var node = heap[index], key = node.key, gpi = this.__getParentIndex;- 88
while (index >= 0) {- 108
var parentIndex = gpi(index), parent = heap[parentIndex];- 108
if (parent && parent.key > key) {- 20
heap[index] = parent;- 20
index = parentIndex;} else {- 88
break;}}- 88
heap[index] = node;},__downHeap : function(index) {- 24
var heap = this.__heap;- 24
var node = heap[index], key = node.key, length = heap.length, max = floor(length / 2), glci = this.__getLeftChildIndex, grci = this.__getRightChildIndex;- 24
while (index < max) {- 16
var leftIndex = glci(index),rightIndex = grci(index), left = heap[leftIndex], right = heap[rightIndex], child, childIndex;- 16
if (rightIndex < length && right.key < left.key) {- 2
childIndex = rightIndex;- 2
child = right;} else {- 14
childIndex = leftIndex;- 14
child = left;}- 16
if (child.key < key) {- 10
heap[index] = child;- 10
index = childIndex;} else {- 6
break;}}- 24
heap[index] = node;}}});
|
collections/Pool.js
|
Coverage100.00
SLOC162
LOC51
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),Queue = require("./Queue"),base = require("../base");/*** @class Base class for a pool.** @name Pool* @memberOf comb.collections** @property {Number} count the total number of objects in the pool, including free and in use objects.* @property {Number} freeCount the number of free objects in this pool.* @property {Number} inUseCount the number of objects in use in this pool.* @property {Number} [minObjects=0] the minimum number of objects this pool should contain.* @property {Number} [maxObjects=1] the maximum number of objects this pool should contain* @ignoreCode*/- 1
exports = module.exports = define(null, {instance : {/**@lends comb.collections.Pool.prototype*/__minObjects : 0,__maxObjects : 1,constructor : function(options) {- 5
options = options || {};- 5
this.__freeObjects = new Queue();- 5
this.__inUseObjects = [];- 5
this.__minObjects = options.minObjects || 0;- 5
this.__maxObjects = options.maxObjects || 1;- 5
this.minObjects = this.__minObjects;- 4
this.maxObjects = this.__maxObjects;},/*** Retrieves an object from this pool.* `* @return {*} an object to contained in this pool*/getObject : function() {- 19
var ret = undefined;- 19
if (this.freeCount > 0) {- 2
ret = this.__freeObjects.dequeue();- 2
this.__inUseObjects.push(ret);- 17
} else if (this.__maxObjects > this.count) {- 12
ret = this.createObject();- 12
this.__inUseObjects.push(ret);}- 19
return ret;},/*** Returns an object to this pool. The object is validated before it is returned to the pool,* if the validation fails then it is removed from the pool;* @param {*} obj the object to return to the pool*/returnObject : function(obj) {- 8
if (this.validate(obj) && this.count <= this.__maxObjects) {- 7
this.__freeObjects.enqueue(obj);- 7
var index;- 7
if ((index = this.__inUseObjects.indexOf(obj)) > -1)- 7
this.__inUseObjects.splice(index, 1);} else {- 1
this.removeObject(obj);}},/*** Removes an object from the pool, this can be overriden to provide any* teardown of objects that needs to take place.** @param {*} obj the object that needs to be removed.** @return {*} the object removed.*/removeObject : function(obj) {- 2
var index;- 2
if (this.__freeObjects.contains(obj)) {- 1
this.__freeObjects.remove(obj);- 1
} else if ((index = this.__inUseObjects.indexOf(obj)) > -1) {- 1
this.__inUseObjects.splice(index, 1);}//otherwise its not contained in this pool;- 2
return obj;},/*** Validates an object in this pool.* </br>* <b>THIS SHOULD BE OVERRIDDEN TO VALIDATE</b>** @param {*} obj the object to validate.*/validate : function(obj) {- 8
return true;},/*** Creates a new object for this pool.* * </br>* <b>THIS SHOULD BE OVERRIDDEN TO ADD THE CORRECT TYPE OF OBJECT</b>** @return {Object} be default just creates an object.*/createObject : function() {- 16
return {};},setters : {minObjects : function(l) {- 6
if (l <= this.__maxObjects) {- 5
this.__minObjects = l;- 5
var i;- 5
if ((i = this.count) < l) {- 1
while (i++ < l) {- 4
this.__freeObjects.enqueue(this.createObject());}}} else {- 1
throw "comb.collections.Pool : minObjects cannot be greater than maxObjects.";}},maxObjects : function(l) {- 9
if (l >= this.__minObjects) {- 8
this.__maxObjects = l;- 8
var i = this.count, j = this.freeCount, fo = this.__freeObjects;- 8
while (i > l && j >= 0) {- 1
this.removeObject(fo.dequeue());- 1
j--;- 1
i--;}} else {- 1
throw "comb.collections.Pool : maxObjects cannot be less than maxObjects.";}}},getters : {freeCount : function() {- 41
return this.__freeObjects.count;},inUseCount : function() {- 14
return this.__inUseObjects.length;},count : function() {- 52
return this.__freeObjects.count + this.__inUseObjects.length;},minObjects : function() {- 2
return this.__minObjects;},maxObjects : function() {- 1
return this.__maxObjects;}}}})
|
collections/PriorityQueue.js
|
Coverage100.00
SLOC41
LOC6
Missed0
|
- 1
var define = require("../define").define,MinHeap = require("./MinHeap"),base = require("../base");- 1
var PriorityQueue;/*** @class PriorityQueue Implementation where the value with the highest priority moves to the front* Priority starts at 0, and the greatest value being the lowest priority;* @name PriorityQueue* @augments comb.collections.MinHeap* @memberOf comb.collections* @ignoreCode*/- 1
PriorityQueue = define(MinHeap, {instance : {/**@lends comb.collections.PriorityQueue.prototype*//*** Adds the value with the specified priority to the queue** @param {Number} priority the priority of the item* </br>* <b>0 = Highest, n = lowest</b>* @param value*/enqueue : function(priority, value) {- 44
return this.insert(priority, value);},/*** Removes the item with the highest priority from the queue** @returns the value of the item*/dequeue : function() {- 16
return this.remove();}}});- 1
module.exports = exports = PriorityQueue;
|
collections/Queue.js
|
Coverage100.00
SLOC119
LOC32
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),base = require("../base");/*** @class <p>FIFO Data structure</p>* @name Queue* @augments comb.collections.Collection* @memberOf comb.collections** @property {Number} count the current number of elements in this queue* @property {Boolean} isEmpty true if this queue is empty* @property {Array} values a copy of the values contained in this queue* @ignoreCode*/- 1
module.exports = exports = define(Collection, {instance : {/**@lends comb.collections.Queue.prototype*/constructor : function() {- 6
this.__queue = [];- 6
this.__next = 0;- 6
this.__last = 0;},/*** Add data to this queue* @param {*} data element to add*/enqueue : function(data) {- 27
this.__queue[this.__last++] = data;},/*** Removes first item from the head of the queue** @return {*} The element removed from this queue. Returns undefined if the queue is empty.*/dequeue : function() {- 7
var ret = undefined,next = this.__next, queue;- 7
if (next != this.__last) {- 5
queue = this.__queue;- 5
ret = queue[next];- 5
queue[this.__next++] = undefined;}- 7
return ret;},/*** Retrieves the item at the head of the queue without removing it** @return {*} The element at the head of the queue. Returns undefined if the queue is empty.*/peek : function() {- 1
var ret = undefined, next = this.__next;- 1
if (next != this.__last) {- 1
ret = this.__queue[next];}- 1
return ret;},/*** Removes all items from this queue*/clear : function() {- 1
this.__queue.length = 0;- 1
this.__next = 0;- 1
this.__last = 0;},/*** Determine if this queue contains the element* @param {*} obj the object to find** @return {Boolean} true if this queue contains the element*/contains : function(obj) {- 5
return this.__queue.indexOf(obj) != -1;},/*** Removes an element from this queue.* @param {*} obj the data to remove.** @return {Boolean} true if the element was removed, false otherwise.*/remove : function(obj) {- 8
var index = this.__queue.indexOf(obj), ret = false;- 8
if (index != -1) {- 8
if (index == this.__next) {- 1
this.dequeue();} else {- 7
this.__queue.splice(index, 1);- 7
this.__last--;}- 8
ret = true;}- 8
return ret;},toString : function(){- 3
return this.__queue.toString();},getters : {count : function() {- 95
return this.__last - this.__next;},isEmpty : function() {- 5
return this.__last - this.__next == 0;},values : function() {- 1
return this.__queue.slice(this.__next, this.__last);}}}});
|
collections/RedBlackTree.js
|
Coverage100.00
SLOC188
LOC101
Missed0
|
- 1
var define = require("../define").define,Tree = require("./Tree"),base = require("../base"),multiply = base.string.multiply;- 1
var RED = "red", BLACK = "black";- 1
var isRed = function(node) {- 1156
return node != null && node.red;};- 1
var makeNode = function(data, parent) {- 122
return {data : data,red : true,left : null,right : null}};- 1
var insert = function(root, data, compare) {- 503
if (root == null) {- 122
return makeNode(data, null);} else {- 381
var cmp = compare(data, root.data);- 381
if (cmp) {- 381
var dir = cmp == -1 ? "left" : "right";- 381
var otherDir = dir == "left" ? "right" : "left";- 381
root[dir] = insert(root[dir], data, compare);- 381
var node = root[dir];- 381
if (isRed(node)) {- 294
var sibling = root[otherDir];- 294
if (isRed(sibling)) {/* Case 1 */- 68
root.red = true;- 68
node.red = false;- 68
sibling.red = false;} else {- 226
if (isRed(node[dir])) {- 43
root = rotateSingle(root, otherDir);- 183
} else if (isRed(node[otherDir])) {- 11
root = rotateDouble(root, otherDir);}}}}}- 381
return root;};- 1
var rotateSingle = function(root, dir) {- 70
var otherDir = dir == "left" ? "right" : "left";- 70
var save = root[otherDir];- 70
root[otherDir] = save[dir];- 70
save[dir] = root;- 70
root.red = true;- 70
save.red = false;- 70
return save;};- 1
var rotateDouble = function(root, dir) {- 12
var otherDir = dir == "left" ? "right" : "left";- 12
root[otherDir] = rotateSingle(root[otherDir], otherDir);- 12
return rotateSingle(root, dir);};- 1
var remove = function (root, data, done, compare) {- 52
if (root == null) {- 2
done.done = true;} else {- 50
var dir;- 50
if (compare(data, root.data) == 0) {- 22
if (root.left == null || root.right == null) {- 16
var save = root[root.left == null ? "right" : "left"];/* Case 0 */- 16
if (isRed(root)) {- 2
done.done = true;- 14
} else if (isRed(save)) {- 5
save.red = false;- 5
done.done = true;}- 16
return save;}else {- 6
var heir = root.right, p;- 6
while (heir.left != null) {- 2
p = heir;- 2
heir = heir.left;}- 6
p && (p.left = null);- 6
root.data = heir.data;- 6
data = heir.data;}}- 34
dir = compare(data, root.data) == -1 ? "left" : "right";- 34
root[dir] = remove(root[dir], data, done, compare);- 34
!done.done && (root = removeBalance(root, dir, done));}- 36
return root;};- 1
var removeBalance = function(root, dir, done) {- 11
var notDir = dir == "left" ? "right" : "left";- 11
var p = root, s = p[notDir];- 11
if (isRed(s)) {- 2
root = rotateSingle(root, dir);- 2
s = p[notDir];}- 11
if (s != null) {- 11
if (!isRed(s.left) && !isRed(s.right)) {- 9
isRed(p) && (done.done = true);- 9
p.red = 0;- 9
s.red = 1;} else {- 2
var save = p.red, newRoot = ( root === p );- 2
p = (isRed(s[notDir]) ? rotateSingle : rotateDouble)(p, dir);- 2
p.red = save;- 2
p.left.red = p.right.red = 0;- 2
if (newRoot) {- 1
root = p;} else {- 1
root[dir] = p;}- 2
done.done = true;}}- 11
return root;};- 1
var RedBlackTree;/*** @class <p>A RedBlack tree is a form of a self balancing binary tree.</p>** <b>Performance</b>* <table>* <tr><td></td><td>Best</td><td>Worst</td></tr>* <tr><td>Space</td><td>O(n)</td><td>O(n)</td></tr>* <tr><td>Search</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>* <tr><td>Delete</td><td>O(log n)</td><td>O(log n)</td></tr>* <table>* @name RedBlackTree* @augments comb.collections.Tree* @memberOf comb.collections* @ignoreCode*/- 1
module.exports = exports = define(Tree, {instance : {/**@lends comb.collections.RedBlackTree.prototype*/insert : function(data) {- 122
this.__root = insert(this.__root, data, this.compare);- 122
this.__root.red = false;},remove : function(data) {- 18
var done = {done : false};- 18
var root = remove(this.__root, data, done, this.compare);- 18
if (root != null)- 17
root.red = 0;- 18
this.__root = root;},__printNode : function(node, level) {- 37
var str = [];- 37
if (node == null || node == undefined) {- 19
str.push(multiply('\t', level));- 19
str.push("~");- 19
console.log(str.join(""));} else {- 18
this.__printNode(node.right, level + 1);- 18
str.push(multiply('\t', level));- 18
str.push((node.red ? "RED" : "BLACK") + ":" + node.data + "\n");- 18
console.log(str.join(""));- 18
this.__printNode(node.left, level + 1);}}}});
|
collections/Stack.js
|
Coverage100.00
SLOC117
LOC30
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),base = require("../base");/*** @class <p>LIFO Data structure</p>* @name Stack* @augments comb.collections.Collection* @memberOf comb.collections** @property {Number} count the current number of elements in this queue* @property {Boolean} isEmpty true if this queue is empty* @property {Array} values a copy of the values contained in this queue* @ignoreCode*/- 1
module.exports = exports = define(Collection, {instance : {/**@lends comb.collections.Stack.prototype*/constructor : function() {- 1
this.__stack = [];- 1
this.__next = -1;},/*** Add an item to the tail of this stack* @param {*} data item to qppend to this stack**/push : function(data) {- 23
this.__stack[++this.__next] = data;},/*** Removes the tail of this static* @return {*} the data at the tail of this stack*/pop : function() {- 11
var ret = undefined, stack, next = this.__next;- 11
if (next >= 0) {- 10
stack = this.__stack;- 10
ret = stack[next];- 10
stack[this.__next--] = undefined;}- 11
return ret;},/*** Retrieves the item at the tail of the stack without removing it** @return {*} The element at the tail of the stack. Returns undefined if the stack is empty.*/peek : function() {- 1
var ret = undefined,next = this.__next;- 1
if (next >= 0) {- 1
ret = this.__stack[next];}- 1
return ret;},/*** Removes all items from this stack.*/clear : function() {- 1
this.__stack.length = 0;- 1
this.__next = -1;},/*** Determine if this stack contains the element* @param {*} obj the object to find** @return {Boolean} true if this stack contains the element*/contains : function(obj) {- 3
return this.__stack.indexOf(obj) != -1;},/*** Removes an element from this stack.* @param {*} obj the data to remove.** @return {Boolean} true if the element was removed, false otherwise.*/remove : function(obj) {- 7
var index = this.__stack.indexOf(obj), ret = false;- 7
if (index != -1) {- 7
if (index == this.__next) {- 1
this.pop();} else {- 6
this.__stack.splice(index, 1);- 6
this.__next--;}- 7
ret = true;}- 7
return ret;},toString : function(){- 3
return this.__stack.toString();},getters : {count : function() {- 3
return this.__next + 1;},isEmpty : function() {- 5
return this.__next < 0;},values : function() {- 1
return this.__stack.slice(0, this.__next + 1).reverse();}}}});
|
collections/Tree.js
|
Coverage100.00
SLOC457
LOC160
Missed0
|
- 1
var define = require("../define").define,Collection = require("./Collection"),Iterable = require("./Iterable"),base = require("../base"),multiply = base.string.multiply;- 1
var compare = function(a, b) {- 2757
var ret = 0;- 2757
if (a > b) {- 1571
return 1;- 1186
} else if (a < b) {- 936
return -1;- 250
}else if(!b){- 1
return 1;}- 249
return ret;};- 1
var Tree = define([Collection, Iterable], {instance : {/**@lends comb.collections.Tree.prototype*//*** Prints a node* @param node node to print* @param level the current level the node is at, Used for formatting*/__printNode : function(node, level) {//console.log(level);- 37
var str = [];- 37
if (node == null || node == undefined) {- 19
str.push(multiply('\t', level));- 19
str.push("~");- 19
console.log(str.join(""));} else {- 18
this.__printNode(node.right, level + 1);- 18
str.push(multiply('\t', level));- 18
str.push(node.data + "\n");- 18
console.log(str.join(""));- 18
this.__printNode(node.left, level + 1);}},/*** Base Class for all tree implementations* @constructs* @augments comb.collections.Collection* @augments comb.collections.Iterable* @memberOf comb.collections** @param {Object} options options to initialize the tree* @param {Function} options.compare function used to compare items in a tree must return an integer* <ul>* </li>-1 for less than</li>* </li>0 for equal</li>* </li>1 for greater than</li>* </ul>**/constructor : function(options) {- 45
options = options || {};- 45
this.compare = options.compare || compare;- 45
this.__root = null;},/*** Inserts an item into the tree* @param {Anything} data the item to insert*/insert : function(data) {- 1
throw new Error("Not Implemented");},/*** Removes an item from the tree* @param {Anything} data the item to insert*/remove : function(data) {- 1
throw new Error("Not Implemented");},/*** Clear all items from a tree*/clear : function() {- 4
this.__root = null;},/*** Test if a tree is empty** @return {Boolean} true if empty false otherwise*/isEmpty : function() {- 15
return this.__root == null;},/*** Traverse a tree until the callback function returns false** <p><b>Not typically used directly</b></p>** @param {Object} node the node to start at* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme* @param {Function} callback called for each item, traversal continues until the function returns false**/traverseWithCondition : function(node, order, callback) {- 2172
var cont = true;- 2172
if (node) {- 1270
order = order || Tree.PRE_ORDER;- 1270
if (order === Tree.PRE_ORDER) {- 152
cont = callback(node.data);- 152
if (cont) {- 144
cont = this.traverseWithCondition(node.left, order, callback);- 144
cont && (cont = this.traverseWithCondition(node.right, order, callback));}- 1118
} else if (order === Tree.IN_ORDER) {- 510
cont = this.traverseWithCondition(node.left, order, callback);- 510
if (cont) {- 444
cont = callback(node.data);- 444
cont && (cont = this.traverseWithCondition(node.right, order, callback));}- 608
} else if (order === Tree.POST_ORDER) {- 178
cont = this.traverseWithCondition(node.left, order, callback);- 178
if (cont) {- 158
cont && (cont = this.traverseWithCondition(node.right, order, callback));- 158
cont && (cont = callback(node.data));}- 430
} else if (order === Tree.REVERSE_ORDER) {- 430
cont = this.traverseWithCondition(node.right, order, callback);- 430
if (cont) {- 384
cont = callback(node.data);- 384
cont && (cont = this.traverseWithCondition(node.left, order, callback));}}}- 2172
return cont;},/*** Traverse a tree** <p><b>Not typically used directly</b></p>** @param {Object} node the node to start at* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme* @param {Function} callback called for each item**/traverse : function(node, order, callback) {- 3449
if (node) {- 1928
order = order || Tree.PRE_ORDER;- 1928
if (order === Tree.PRE_ORDER) {- 632
callback(node.data);- 632
this.traverse(node.left, order, callback);- 632
this.traverse(node.right, order, callback);- 1296
} else if (order === Tree.IN_ORDER) {- 632
this.traverse(node.left, order, callback);- 632
callback(node.data);- 632
this.traverse(node.right, order, callback);- 664
} else if (order === Tree.POST_ORDER) {- 632
this.traverse(node.left, order, callback);- 632
this.traverse(node.right, order, callback);- 632
callback(node.data);- 32
} else if (order === Tree.REVERSE_ORDER) {- 32
this.traverseWithCondition(node.right, order, callback);- 32
callback(node.data);- 32
this.traverseWithCondition(node.left, order, callback);}}},/*** Loop through each item in the tree* @param {Function} cb called for each item in the tree* @param {Object} [scope=this] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme*/forEach : function(cb, scope, order) {- 28
if (typeof cb !== "function")- 4
throw new TypeError();- 24
order = order || Tree.IN_ORDER;- 24
scope = scope || this;- 24
this.traverse(this.__root, order, function(node) {- 312
cb.call(scope, node, this);});},/*** Loop through each item in the tree, collecting the value returned by the callback funciton.* @param {Function} cb called for each item in the tree.* Whatever the function returns is inserted into the return tree* @param {Object} [scope=this] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return {comb.collections.Tree} the tree with the mapped items*/map : function(cb, scope, order) {- 28
if (typeof cb !== "function")- 4
throw new TypeError();- 24
order = order || Tree.IN_ORDER;- 24
scope = scope || this;- 24
var construct = this._static;- 24
var ret = new this._static();- 24
this.traverse(this.__root, order, function(node) {- 312
ret.insert(cb.call(scope, node, this));});- 24
return ret;},/*** Filters a tree, only returning items that result in true being returned from the callback** @param {Function} cb called for each item in the tree* @param {Object} [scope=this] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return {comb.collections.Tree} the tree with items that resulted in true being returned from the callback*/filter : function(cb, scope, order) {- 16
if (typeof cb !== "function")- 4
throw new TypeError();- 12
order = order || Tree.IN_ORDER;- 12
scope = scope || this;- 12
var ret = new this._static();- 12
this.traverse(this.__root, order, function(node) {- 216
var include = cb.call(scope, node, this);- 216
include && ret.insert(node);});- 12
return ret;},/*** Reduces a tree** @param {Function} fun called for each item in the tree* @param [accumulator=First item in tree(Order dependant)] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return the result of the reduce function*/reduce : function(fun, accumulator, order) {- 36
var arr = this.toArray(order);- 36
var args = [fun];- 36
!base.isUndefinedOrNull(accumulator) && args.push(accumulator)- 36
return arr.reduce.apply(arr, args);},/*** Reduces from right to left** @param {Function} fun called for each item in the tree* @param [accumulator=First item in tree(Order dependant)] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return the result of the reduce function*/reduceRight : function(fun, accumulator, order) {- 12
var arr = this.toArray(order);- 12
var args = [fun];- 12
!base.isUndefinedOrNull(accumulator) && args.push(accumulator)- 12
return arr.reduceRight.apply(arr, args);},/*** Determines if every item meets the condition returned by the callback.** @param {Function} cb called for each item in the tree* @param {Object} [scope=this] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return {Boolean} True if every item passed false otherwise*/every : function(cb, scope, order) {- 36
if (typeof cb !== "function")- 4
throw new TypeError();- 32
order = order || Tree.IN_ORDER;- 32
scope = scope || this;- 32
var ret = false;- 32
this.traverseWithCondition(this.__root, order, function(node) {- 264
return (ret = cb.call(scope, node, this));});- 32
return ret;},/*** Determines if some item meet the condition returned by the callback. Traversal ends the first time true is found.** @param {Function} cb called for each item in the tree* @param {Object} [scope=this] scope to call the function in* @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return {Boolean} True if every item passed false otherwise*/some : function(cb, scope, order) {- 36
if (typeof cb !== "function")- 4
throw new TypeError();- 32
order = order || Tree.IN_ORDER;- 32
scope = scope || this;- 32
var ret;- 32
this.traverseWithCondition(this.__root, order, function(node) {- 284
ret = cb.call(scope, node, this);- 284
return !ret;});- 32
return ret;},/*** Converts a tree into an array based on the specified order** @param {Tree.PRE_ORDER|Tree.POST_ORDER|Tree.IN_ORDER|Tree.REVERSE_ORDER} [order=Tree.IN_ORDER] the traversal scheme** @return {Array} array of all items in the order specified.*/toArray : function(order) {- 72
order = order || Tree.IN_ORDER;- 72
var arr = [];- 72
this.traverse(this.__root, order, function(node) {- 1056
arr.push(node);});- 72
return arr;},/*** Determines if a value is contained in the tree* @param {*} value the value to find** @return {Boolean} true if the tree contains the item false otherwise.*/contains : function(value) {- 160
var ret = false;- 160
var root = this.__root;- 160
while (root != null) {- 376
var cmp = this.compare(value, root.data);- 376
if (cmp) {- 271
root = root[(cmp == -1) ? "left" : "right"];} else {- 105
ret = true;- 105
root = null;}}- 160
return ret;},/*** Finds a value in the tree* @param {*} value the value to find** @return the value of the node that matched*/find : function(value) {- 8
var ret;- 8
var root = this.__root;- 8
while (root != null) {- 35
var cmp = this.compare(value, root.data);- 35
if (cmp) {- 31
root = root[(cmp == -1) ? "left" : "right"];} else {- 4
ret = root.data;- 4
break;}}- 8
return ret;},/*** Find all values less than a value* @param {*} value the value to find nodes less than* @param {Boolean} [exclusive=false] if true the value will NOT be included in the return array** @return {Array} the array containing all values less than*/findLessThan : function(value, exclusive) {//find a better way!!!!- 32
var ret = [], compare = this.compare;- 32
this.traverseWithCondition(this.__root, exports.IN_ORDER, function(v) {- 200
var cmp = compare(value, v);- 200
if ((!exclusive && cmp == 0) || cmp == 1) {- 168
ret.push(v);- 168
return true;} else {- 32
return false;}});- 32
return ret;},/*** Find all greater than a value* @param {*} value the value to find nodes greater than* @param {Boolean} [exclusive=false] if true the value will NOT be included in the return array** @return {Array} the array containing all values greater than*/findGreaterThan : function(value, exclusive) {//find a better way!!!!- 32
var ret = [], compare = this.compare;- 32
this.traverse(this.__root, exports.REVERSE_ORDER, function(v) {- 416
var cmp = compare(value, v);- 416
if ((!exclusive && cmp == 0) || cmp == -1) {- 372
ret.push(v);- 372
return true;} else {- 44
return false;}});- 32
return ret;},/*** Prints a tree to the console.*/print : function() {- 4
this.__printNode(this.__root, 0);}},static : {/** @lends comb.collections.Tree *//*** Pre Order*/PRE_ORDER : "pre_order",/*** In Order*/IN_ORDER : "in_order",/*** Post Order*/POST_ORDER:"post_order",/*** Reverse Order*/REVERSE_ORDER : "reverse_order"}});/**@ignore*/- 1
module.exports = exports = Tree;
|
collections/index.js
|
Coverage100.00
SLOC21
LOC2
Missed0
|
- 1
var comb = exports;/*** @ignore* @namespace Various collections*/- 1
comb.collections = {Collection : require("./Collection"),Iterable : require("./Iterable"),Tree : require("./Tree"),BinaryTree : require("./BinaryTree"),RedBlackTree : require("./RedBlackTree"),AnderssonTree : require("./AnderssonTree"),AVLTree : require("./AVLTree"),HashTable : require("./HashTable"),Queue : require("./Queue"),Stack : require("./Stack"),Heap : require("./Heap"),MinHeap : require("./MinHeap"),MaxHeap : require("./MaxHeap"),PriorityQueue : require("./PriorityQueue"),Pool : require("./Pool")};
|
define.js
|
Coverage100.00
SLOC553
LOC157
Missed0
|
/*** Used to keep track of classes and to create unique ids* @ignore*/- 1
var classCounter = 0, Base,_base = require("./base"),isHash = _base.isHash,isArray = _base.isArray;- 1
function callSuper(args, a) {- 1245
var meta = this.__meta,supers = meta.supers,l = supers.length, superMeta = meta.superMeta, pos = superMeta.pos;- 1245
if (l > pos) {- 1245
a && (args = a);- 1245
var name = superMeta.name, f = superMeta.f, m;- 1245
do {- 1245
m = supers[pos][name];- 1245
if ("function" === typeof m && (m = m._f || m) !== f) {- 1241
superMeta.pos = 1 + pos;- 1241
return m.apply(this, args);}} while (l > ++pos);}- 4
return null;}- 1
function getSuper() {- 2
var meta = this.__meta,supers = meta.supers,l = supers.length, superMeta = meta.superMeta, pos = superMeta.pos;- 2
if (l > pos) {- 2
var name = superMeta.name, f = superMeta.f, m;- 2
do {- 3
m = supers[pos][name];- 3
if ("function" === typeof m && (m = m._f || m) !== f) {- 1
superMeta.pos = 1 + pos;- 1
return m.bind(this);}} while (l > ++pos);}- 1
return null;}- 1
function defaultFunction() {- 287
var meta = this.__meta || {},supers = meta.supers,l = supers.length, superMeta = meta.superMeta, pos = superMeta.pos;- 287
if (l > pos) {- 143
var name = superMeta.name, f = superMeta.f, m;- 143
do {- 223
m = supers[pos][name];- 223
if ("function" === typeof m && (m = m._f || m) !== f) {- 96
superMeta.pos = 1 + pos;- 96
return m.apply(this, arguments);}} while (l > ++pos);}- 191
return null;}- 1
function functionWrapper(f, name) {- 316
var wrapper = function () {- 39197
var ret, meta = this.__meta || {};- 39197
var orig = meta.superMeta;- 39197
meta.superMeta = {f: f, pos: 0, name: name};- 39197
ret = f.apply(this, arguments);- 39148
meta.superMeta = orig;- 39148
return ret;};- 316
wrapper._f = f;- 316
return wrapper;}/*** @ignore*/- 1
function defineMixinProps(child, proto) {- 34
var operations = proto.setters || {};- 34
for (var i in operations) {- 15
if (!child.__lookupSetter__(i)) { //make sure that the setter isnt already there- 15
child.__defineSetter__(i, operations[i]);}}- 34
operations = proto.getters || {};- 34
for (i in operations) {- 15
if (!child.__lookupGetter__(i)) {//define the getter if the child does not already have it- 15
child.__defineGetter__(i, operations[i]);}}- 34
for (var j in proto) {- 103
if (j != "getters" && j != "setters") {- 83
var p = proto[j];- 83
if ("function" === typeof p) {- 78
if (!child.hasOwnProperty(j)) {- 10
child[j] = functionWrapper(defaultFunction, j);}} else {- 5
child[j] = p;}}}}/*** @ignore*/- 1
function mixin() {- 7
var args = Array.prototype.slice.call(arguments), l = args.length;- 7
var child = this.prototype, childMeta = child.__meta, thisMeta = this.__meta, bases = child.__meta.bases, staticBases = bases.slice(),staticSupers = thisMeta.supers || [], supers = childMeta.supers || [];- 7
for (var i = 0; i < l; i++) {- 17
var m = args[i], mProto = m.prototype;- 17
var protoMeta = mProto.__meta, meta = m.__meta;- 17
!protoMeta && (protoMeta = (mProto.__meta = {proto: mProto || {}}));- 17
!meta && (meta = (m.__meta = {proto: m.__proto__ || {}}));- 17
defineMixinProps(child, protoMeta.proto || {});- 17
defineMixinProps(this, meta.proto || {});//copy the bases for static,- 17
mixinSupers(m.prototype, supers, bases);- 17
mixinSupers(m, staticSupers, staticBases);}- 7
return this;}/*** @ignore*/- 1
function mixinSupers(sup, arr, bases) {- 386
var meta = sup.__meta;- 386
!meta && (meta = (sup.__meta = {}));- 386
var unique = sup.__meta.unique;- 386
!unique && (meta.unique = "define" + ++classCounter);//check it we already have this super mixed into our prototype chain//if true then we have already looped their supers!- 386
if (bases.indexOf(unique) == -1) {//add their id to our bases- 234
bases.push(unique);- 234
var supers = sup.__meta.supers || [], i = supers.length - 1 || 0;- 234
while (i >= 0) {- 258
mixinSupers(supers[i--], arr, bases);}- 234
arr.unshift(sup);}}/*** @ignore*/- 1
function defineProps(child, proto) {- 92
var operations = proto.setters;- 92
if (operations) {- 8
for (var i in operations) {- 13
child.__defineSetter__(i, operations[i]);}}- 92
operations = proto.getters || {};- 92
if (operations) {- 92
for (i in operations) {- 47
child.__defineGetter__(i, operations[i]);}}- 92
for (i in proto) {- 357
if (i != "getters" && i != "setters") {- 336
var f = proto[i];- 336
if ("function" === typeof f) {- 303
var meta = f.__meta || {};- 303
if (!meta.isConstructor) {- 302
child[i] = functionWrapper(f, i);} else {- 1
child[i] = f;}} else {- 33
child[i] = f;}}}}- 1
function _export(obj, name) {- 11
if (obj && name) {- 2
obj[name] = this;} else {- 9
obj.exports = obj = this;}- 11
return this;}- 1
function extend(proto) {- 3
return define(this, proto);}/*** @ignore*/- 1
function __define(child, sup, proto) {- 48
var childProto = child.prototype, supers = [];- 48
var unique = "define" + ++classCounter, bases = [], staticBases = [];- 48
var instanceSupers = [], staticSupers = [];- 48
var meta = childProto.__meta = {supers: instanceSupers,unique: unique,bases: bases,superMeta: {f: null,pos: 0,name: null}};- 48
var childMeta = child.__meta = {supers: staticSupers,unique: unique,bases: staticBases,isConstructor: true,superMeta: {f: null,pos: 0,name: null}};- 48
if ((isHash(sup) && !proto)) {- 2
proto = sup;- 2
sup = Base;- 46
} else if ((!sup && isHash(proto))) {- 14
sup = Base;}- 48
if ("function" === typeof sup || isArray(sup)) {- 47
supers = isArray(sup) ? sup : [sup];- 47
sup = supers.shift();- 47
child.__proto__ = sup;- 47
childProto.__proto__ = sup.prototype;- 47
mixinSupers(sup.prototype, instanceSupers, bases),mixinSupers(sup, staticSupers, staticBases);}- 48
if (proto) {- 46
var instance = meta.proto = proto.instance || {};- 46
!instance.hasOwnProperty("constructor") && (instance.constructor = defaultFunction);- 46
var stat = childMeta.proto = proto.static || {};- 46
stat.init = stat.init || defaultFunction;- 46
defineProps(childProto, instance, false);- 46
defineProps(child, stat, true);} else {- 2
meta.proto = {};- 2
childMeta.proto = {};- 2
child.init = functionWrapper(defaultFunction, "init");- 2
childProto.constructor = functionWrapper(defaultFunction, "constructor");}- 48
if (supers.length) {- 7
mixin.apply(child, supers);}- 48
childProto._super = child._super = callSuper;- 48
childProto._getSuper = child._getSuper = getSuper;- 48
childProto._static = child;}- 1
function define(sup, proto) {- 45
function defineConstructor() {- 3171
this.constructor.apply(this, arguments);}- 45
__define(defineConstructor, sup, proto);- 45
return defineConstructor.init() || defineConstructor;}- 1
function singleton(sup, proto) {- 3
var retInstance;- 3
function singletonConstructor() {- 6
if (!retInstance) {- 2
this.constructor.apply(this, arguments);- 2
retInstance = this;}- 6
return retInstance;}- 3
__define(singletonConstructor, sup, proto);- 3
return singletonConstructor.init() || singletonConstructor;}- 1
Base = define({instance: {},"static": {mixin: mixin,extend: extend,as: _export}});/*** Defines a new class to be used** <p>* Class methods* <ul>* <li>as(module | object, name): exports the object to module or the object with the name</li>* <li>mixin(mixin) : mixes in an object</li>* </ul>* </br>* Instance methods* <ul>* <li>_super(argumnents, [?newargs]): calls the super of the current method</li>* </ul>** </br>* Instance properties* <ul>* <li>_static: use to reference class properties and methods</li>* </ul>** </p>*** @example* //Class without a super class* var Mammal = comb.define(null, {* instance : {** constructor: function(options) {* options = options || {};* this._super(arguments);* this._type = options.type || "mammal";* },** speak : function() {* return "A mammal of type " + this._type + " sounds like";* },** //Define your getters* getters : {* type : function() {* return this._type;* }* },** //Define your setters* setters : {* type : function(t) {* this._type = t;* }* }* },** //Define your static methods* static : {* soundOff : function() {* return "Im a mammal!!";* }* }* });** //Show singular inheritance*var Wolf = comb.define(Mammal, {* instance: {* constructor: function(options) {* options = options || {};* //You can call your super constructor, or you may not* //call it to prevent the super initializing parameters* this._super(arguments);* this._sound = "growl";* this._color = options.color || "grey";* },** speak : function() {* //override my super classes speak* //Should return "A mammal of type mammal sounds like a growl"* return this._super(arguments) + " a " + this._sound;* },** //add new getters for sound and color* getters : {** color : function() {* return this._color;* },** sound : function() {* return this._sound;* }* },** setters : {** //NOTE color is read only except on initialization** sound : function(s) {* this._sound = s;* }* }** },** static : {* //override my satic soundOff* soundOff : function() {* //You can even call super in your statics!!!* //should return "I'm a mammal!! that growls"* return this._super(arguments) + " that growls";* }* }*});*** //Typical hierarchical inheritance* // Mammal->Wolf->Dog* var Dog = comb.define(Wolf, {* instance: {* constructor: function(options) {* options = options || {};* this._super(arguments);* //override Wolfs initialization of sound to woof.* this._sound = "woof";** },** speak : function() {* //Should return "A mammal of type mammal sounds like a growl thats domesticated"* return this._super(arguments) + " thats domesticated";* }* },** static : {* soundOff : function() {* //should return "I'm a mammal!! that growls but now barks"* return this._super(arguments) + " but now barks";* }* }*});**** dog instanceof Wolf => true* dog instanceof Mammal => true* dog.speak() => "A mammal of type mammal sounds like a woof thats domesticated"* dog.type => "mammal"* dog.color => "gold"* dog.sound => "woof"* Dog.soundOff() => "Im a mammal!! that growls but now barks"** // Mammal->Wolf->Dog->Breed*var Breed = comb.define(Dog, {* instance: {** //initialize outside of constructor* _pitch : "high",** constructor: function(options) {* options = options || {};* this._super(arguments);* this.breed = options.breed || "lab";* },** speak : function() {* //Should return "A mammal of type mammal sounds like a* //growl thats domesticated with a high pitch!"* return this._super(arguments) + " with a " + this._pitch + " pitch!";* },** getters : {* pitch : function() {* return this._pitch;* }* }* },** static : {* soundOff : function() {* //should return "I'M A MAMMAL!! THAT GROWLS BUT NOW BARKS!"* return this._super(arguments).toUpperCase() + "!";* }* }* });*** var breed = new Breed({color : "gold", type : "lab"}),**** breed instanceof Dog => true* breed instanceof Wolf => true* breed instanceof Mammal => true* breed.speak() => "A mammal of type lab sounds like a woof "* + "thats domesticated with a high pitch!"* breed.type => "lab"* breed.color => "gold"* breed.sound => "woof"* breed.soundOff() => "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"*** //Example of multiple inheritance* //NOTE proto is optional** //Mammal is super class* //Wolf Dog and Breed inject functionality into the prototype* var Lab = comb.define([Mammal, Wolf, Dog, Breed]);** var lab = new Lab();* lab instanceof Wolf => false* lab instanceof Dog => false* lab instanceof Breed => false* lab instanceof Mammal => true* lab.speak() => "A mammal of type mammal sounds like a"* + " woof thats domesticated with a high pitch!"* Lab.soundOff() => "IM A MAMMAL!! THAT GROWLS BUT NOW BARKS!"** @name define* @memberOf comb** @param {Array|Class} super the supers of this class* @param {Object} [proto] the object used to define this class* @param {Object} [proto.instance] the instance methods of the class* @param {Object} [proto.instance.getters] the getters for the class* @param {Object} [proto.instance.setters] the setters for the class* @param {Object} [proto.static] the Class level methods of this class* @param {Object} [proto.static.getters] static getters for the object* @param {Object} [proto.static.setters] static setters for the object** @returns {Object} the constructor of the class to be used with new keyword*/- 1
exports.define = define;/*** Defines a singleton instance of a Class. See {@link define}* @example* var MyLab = comb.singleton([Mammal, Wolf, Dog, Breed]);* var myLab1 = new MyLab();* myLab1.type = "collie"* var myLab2 = new MyLab();* myLab1 === myLab2 => true* myLab1.type => "collie"* myLab2.type => "collie"*** @name singleton* @memberOf comb*/- 1
exports.singleton = singleton;
|
extensions/arguments.js
|
Coverage100.00
SLOC14
LOC4
Missed0
|
- 1
var base = require("../base"),utils = require("./utils"),extend = utils.extend,array = base.array;- 1
var methods = [["argsToArray", "toArray"]];- 1
module.exports = function (o) {- 4
return extend(o, methods, base);};
|
extensions/array.js
|
Coverage100.00
SLOC21
LOC7
Missed0
|
- 1
var base = require("../base"),array = base.array,string = base.string,utils = require("./utils"),extend = utils.extend;- 1
var stringMethods = ["style"];- 1
var methods = ["forEach", "map", "filter", "reduce", "reduceRight", "some", "every", "indexOf", "lastIndexOf","zip", "sum", "avg", "sort", "min", "max", "difference", "removeDuplicates", "unique", "rotate","permutations", "transpose", "valuesAt", "union", "intersect", "powerSet", "cartesian", "compact","multiply", "flatten", "pluck", "invoke"];- 1
module.exports = function (o) {- 183
extend(o, methods, array);- 183
extend(o, stringMethods, string);- 183
return o;};
|
extensions/cast.js
|
Coverage100.00
SLOC45
LOC13
Missed0
|
- 1
var base = require("../base"),define = require("../define").define,utils = require("./utils"),extend = utils.extend,arrayExtension = require("./array"),argumentsExtension = require("./arguments"),dateExtension = require("./date"),functionExtension = require("./function"),numberExtension = require("./number"),objectExtension = require("./object"),stringExtension = require("./string");- 1
var methods = {array:function () {- 183
return arrayExtension(this);},date:function () {- 277
return dateExtension(this);},args:function () {- 4
return argumentsExtension(this);},func:function () {- 42
return functionExtension(this);},number:function () {- 159
return numberExtension(this);},string:function () {- 485
return stringExtension(this);},object:function () {- 516
return objectExtension(this);}};- 1
module.exports = function (o) {- 1194
extend(o, Object.keys(methods), methods, function (name, func) {- 8358
return base.partial(func);});- 1194
return o;};
|
extensions/date.js
|
Coverage100.00
SLOC26
LOC5
Missed0
|
- 1
var base = require("../base"),define = require("../define").define,utils = require("./utils"),extend = utils.extend,date = base.date,string = base.string;- 1
var methods = ["add","compare","difference","format","getDaysInMonth","getTimezoneName","isLeapYear","isWeekend"];- 1
module.exports = function (o) {- 277
extend(o, methods, date);- 277
return o;};
|
extensions/function.js
|
Coverage100.00
SLOC42
LOC16
Missed0
|
- 1
var base = require("../base"),argsToArray = base.argsToArray,utils = require("./utils"),array = base.array,extend = utils.extend,comb;- 1
var methods = ["hitch","bind","hitchIgnore","bindIgnore","partial","applyFirst","bindFirst","curry","extend"];- 1
var baseMethods = ["extend"];- 1
module.exports = function (o) {- 42
comb = comb || (require("../index"));- 42
extend(o, methods, base, function (name, func) {- 378
var ret;- 378
if (name !== 'partial' && name !== "applyFirst") {- 294
ret = function (arg1) {- 7
var args = argsToArray(arguments, 1);- 7
return comb(func.apply(null, [arg1, this].concat(args)));};} else {- 84
ret = function (arg1) {- 3
return comb(func.apply(null, [this].concat(argsToArray(arguments))));};}- 378
return ret;});- 42
extend(o, baseMethods, base);- 42
return o;};
|
extensions/index.js
|
Coverage100.00
SLOC47
LOC24
Missed0
|
- 1
var base = require("../base"),stringExtension = require("./string"),functionExtension = require("./function"),objectExtension = require("./object"),argumentsExtension = require("./arguments"),dateExtension = require("./date"),isExtension = require("./is"),castExtension = require("./cast.js"),numberExtension = require("./number"),arrayExtension = require("./array");- 1
var TRUE = isExtension(true),FALSE = isExtension(false);- 1
function createExtension(obj) {- 1268
if (base.isBoolean(obj)) {- 17
return obj ? TRUE : FALSE;}- 1251
if (!base.isUndefinedOrNull(obj) && !obj.__isExtended__) {- 1194
obj = isExtension(obj);- 1194
obj = castExtension(obj);- 1194
if (obj.isObject()) {- 516
obj.object();}- 1194
if (obj.isArguments()) {- 4
obj.args();}- 1194
if (obj.isArray()) {- 183
obj.array();}- 1194
if (obj.isFunction()) {- 42
obj.func();}- 1194
if (obj.isString()) {- 485
obj.string();}- 1194
if (obj.isDate()) {- 275
obj.date();}- 1194
if (obj.isNumber()) {- 159
obj.number();}}- 1251
return obj;}- 1
exports.createExtension = createExtension;
|
extensions/is.js
|
Coverage100.00
SLOC87
LOC28
Missed0
|
- 1
var base = require("../base"),define = require("../define").define,utils = require("./utils"),extend = utils.extend;- 1
var methods = ["isDefined","isUndefined","isNull","isUndefinedOrNull","isArguments","isObject","isHash","isBoolean","isDate","isEmpty","isArray","isFunction","isInstanceOf","isNumber","isPromiseLike","isRegExp","isString","deepEqual"];- 1
module.exports = function (o) {- 1196
var valueOf = false, val;- 1196
if (!base.isInstanceOf(o, Object)) {- 638
if (base.isBoolean(o)) {- 2
val = new Boolean(o);- 2
valueOf = true;- 636
} else if (base.isNumber(o)) {- 155
val = new Number(o);- 155
valueOf = true;- 481
} else if (base.isString(o)) {- 481
val = new String(o);- 481
valueOf = true;}} else {- 558
val = o;}- 1196
var ret = extend(val, methods, base, null, valueOf);- 1196
if (valueOf) {- 638
Object.defineProperty(ret, "valueOf", {value:function () {- 5094
return o;},writable:false,enumerable:false,configurable:true});}- 1196
Object.defineProperty(ret, "eq", {value:function (other) {- 6
return o === other;},writable:false,enumerable:false,configurable:true});- 1196
Object.defineProperty(ret, "neq", {value:function (other) {- 6
return o !== other;},writable:false,enumerable:false,configurable:true});- 1196
Object.defineProperty(ret, "print", {value:function () {- 3
console.log(o);- 3
return val;},writable:false,enumerable:false,configurable:true});- 1196
Object.defineProperty(ret, "__isExtended__", {value:true,writable:false,enumerable:false,configurable:true});- 1196
return ret;};
|
extensions/number.js
|
Coverage100.00
SLOC17
LOC5
Missed0
|
- 1
var base = require("../base"),define = require("../define").define,utils = require("./utils"),extend = utils.extend,number = base.number,string = base.string;- 1
var methods = ["round","roundCeil"];- 1
module.exports = function (o) {- 159
extend(o, methods, number, null, true);- 159
return o;};
|
extensions/object.js
|
Coverage100.00
SLOC38
LOC12
Missed0
|
- 1
var base = require("../base"),define = require("../define").define,utils = require("./utils"),extend = utils.extend,hash = base.hash,argsToArray = base.argsToArray,comb;- 1
var methods = ["hitch","hitchIgnore","bind","bindIgnore","merge","extend","deepMerge"];- 1
var lastMethod = ["curry"];- 1
var hashMethods = ["forEach","filter","invert","values","toArray"];- 1
module.exports = function (o) {- 516
comb = comb || (require("../index"));- 516
extend(o, methods, base);- 516
extend(o, hashMethods, hash);- 516
extend(o, lastMethod, base, function (name, func) {- 516
return function () {- 1
return comb(func.apply(null, argsToArray(arguments).concat([this])));};});- 516
return o;};
|
extensions/string.js
|
Coverage100.00
SLOC45
LOC21
Missed0
|
- 1
var base = require("../base"),string = base.string,date = base.date,utils = require("./utils"),extend = utils.extend,regexp = base.regexp,array = base.array,argsToArray = base.argsToArray,comb;- 1
var methods = ["style", "multiply", "toArray", "format", "truncate", "pad"];- 1
var baseMethods = ["camelize", "underscore", "classify", "pluralize", "singularize", "applyFirst", "bindFirst", "partial"];- 1
var functionMethods = ["hitch", "bind", "hitchIgnore", "bindIgnore","curry"];- 1
var arrayMethods = ["pluck", "invoke"];- 1
var dateMethods = [["parse", "parseDate"]];- 1
var regexpMethods = [["escapeString", "escape"]];- 1
module.exports = function (o) {- 485
comb = comb || (require("../index"));- 485
extend(o, methods, string, null, true);- 485
extend(o, baseMethods, base, null, true);- 485
extend(o, dateMethods, date, null, true);- 485
extend(o, regexpMethods, regexp, null, true);- 485
extend(o, arrayMethods, array, function (name, func) {- 970
return function () {- 7
return comb(func.apply(null, argsToArray(arguments).concat([this.valueOf()])));};}, true);- 485
extend(o, functionMethods, base, function (name, func) {- 2425
return function (arg1) {- 3
var args = argsToArray(arguments, 1);- 3
return comb(func.apply(null, [arg1, this.valueOf()].concat(args)));};});- 485
return o;};
|
extensions/utils.js
|
Coverage100.00
SLOC45
LOC19
Missed0
|
- 1
var define = require("../define").define,base = require("../base"),array = base.array,isBoolean = base.isBoolean,argsToArray = base.argsToArray,comb;- 1
function proxyFunc(name, func, valueOf, scope) {- 43916
return function proxy() {- 9055
comb || (comb = require("../index"));- 9055
var ret = func.apply(scope, [valueOf ? this.valueOf() : this].concat(argsToArray(arguments)));- 9052
if (ret && !base.isBoolean(ret) && ret !== this && !ret.__isExtended__) {- 569
ret = comb(ret);}- 9052
return ret;};}- 1
function extend(obj, methods, base, creator, valueOf) {- 7738
valueOf = isBoolean(valueOf) ? valueOf : false;- 7738
array.forEach(methods, function (method) {- 56563
var newFunc, func, m, name;- 56563
if (Array.isArray(method) && method.length === 2) {- 974
m = method[0];- 974
name = method[1];} else {- 55589
m = name = method;}- 56563
Object.defineProperty(obj, name, {value:(creator || proxyFunc)(name, base[m], valueOf, base),writable:false,enumerable:false,configurable:true});});- 7738
return obj;}- 1
module.exports = {proxyFunc:proxyFunc,extend:extend};
|
index.js
|
Coverage100.00
SLOC110
LOC8
Missed0
|
- 1
var base = require("./base"),extension = require("./extensions"),createExtension = extension.createExtension;/*** @projectName comb** @github https://github.com/C2FO/comb** @includeDoc [Getting Started] ../docs-md/introduction.md* @includeDoc [OO] ../docs-md/define.md* @includeDoc [Promises] ../docs-md/promise.md* @includeDoc [Logging] ../docs-md/logging.md* @includeDoc [Utilities] ../docs-md/utilities.md* @includeDoc [Change Log] ../History.md* @includeDoc [Test Coverage] [../docs-md/coverage.html]*** @header* [](http://travis-ci.org/C2FO/comb)* #Comb** ##Overview** Framework for node that provides a one stop shop for frequently needed utilities, including:** * [OO utilties](./define.html)* * Collections* * [Logging](./logging.html)* * [String & date formatting](./utilities)* * [Flow control](./promise.html)*** ##Installation** `npm install comb`** ###[Getting Started](./introduction.html)** ##Highlights** * 100% test coverage!* * comb([define](./comb.html#.define)|[singleton](./comb.html#.singleton))* * The backbone of comb.* * Options for classical inheritance models as well as mixins(pseudo multi-inheritance)* * You can call this._super from any method. Including statically defined ones!* * Access to your class level properties within an instance* * Logging* * Logger inheritance through name spaces* * Predefined [level](./comb_logging_Level.html) level definition along with the ability to define your own.* * Multiple appenders including* * [FileAppender](./comb_logging_appenders_FileAppender.html) - log it to a file* * [RollingFileAppender](./comb_logging_appenders_RollingFileAppender.html) - log it to a file up to a customizable size then create a new one.* * [JSONAppender](./comb_logging_appenders_JSONAppender.html) - write it out as JSON to a file.* * [ConsoleAppender](./comb_logging_appenders_ConsoleAppender.html)- log it to the console* * Configurable with [files OR programatically](./comb_logger.html#.configure)* * Collections* * [RedBlackTree](./comb_collections_RedBlackTree.html)* * [AVLTree](./comb_collections_AVLTree.html)* * [AnderssonTree](./comb_collections_AnderssonTree.html)* * [BinaryTree](./comb_collections_BinaryTree.html)* * [HashTable](./comb_collections_HashTable.html)* * [MaxHeap](./comb_collections_MaxHeap.html)* * [MinHeap](./comb_collections_MinHeap.html)* * [Pool](./comb_collections_Pool.html)* * [PriorityQueue](./comb_collections_PriorityQueue.html)* * [Queue](./comb_collections_Queue.html)* * [Stack](./comb_collections_Stack.html)** * [Flow control](./promise.html)* * [Promises](./comb_Promise.html)* * [PromiseList](./comb_PromiseList.html)* * [comb.when](./comb.html#.when)* * [comb.serial](./comb.html#.serial)** @footer* ##License** MIT <https://github.com/C2FO/comb/raw/master/LICENSE>** ##Meta* * Code: `git clone git://github.com/C2FO/comb.git`* * Website: <http://c2fo.com>* * Twitter: [http://twitter.com/c2fo](http://twitter.com/c2fo) - 877.465.4045*//*** Utilities for javascript, optimized for the server environment.*** @namespace* @ignoreCode*/- 1
var comb = createExtension;- 1
base.merge(comb, base, require("./define"), require("./promise"), require("./async"), require("./plugins"), require("./collections"), require("./logging"));- 1
comb.definePlugin = function (obj) {- 1
if (comb.isHash(obj)) {- 1
comb.deepMerge(comb, obj);}- 1
return comb;};- 1
module.exports = comb;
|
logging/appenders/appender.js
|
Coverage100.00
SLOC167
LOC30
Missed0
|
- 1
var define = require("../../define.js").define, base = require("../../base"), Level = require("../level");- 1
var APPENDER_TYPES = {};/*** @class Base class for all appenders** @name Appender* @memberOf comb.logging.appenders** @param {Object} [options] options to assign to this Appender* @param {String} [options.name="appender"] the name of this Appender. If you want two of the same type of appender* on a logger it must have a different name.* @param {String} [options.pattern="[{[yyyy-MM-ddTHH:mm:ss:SSS (z)]timeStamp}] {[- 5]levelName} {[-20]name} - {message}"]* <p>Available Options for formatting see {@link comb.string.format} for formatting options</p>* <ul>* <li>timeStamp - the timestamp of the event being logged</li>* <li>level - the {@link comb.logging.Level} of the event</li>* <li>levelName - the name of the level being logged</li>* <li>name - the name of the logger logging the event</li>* <li>message - the message being logged</li>* </ul>* @param {comb.logging.Level|String} [options.level=comb.logging.Level.INFO] the logging level of this appender* <p><b>Note:</b> the level can be different from the logger in the case that you want a particular logger* to only log particular event of a level. For example an appender that only logs errors. BEWARE that if the* appenders level is lower than the logger is will not receive any messages.</p>** @property {String} name the name of this Appender.* @property {String} pattern the pattern for this Appender.* @property {comb.logging.Level} level the level of this Appender.* @ignoreCode*/- 1
define(null, {instance:{/**@lends comb.logging.appenders.Appender.prototype*/constructor:function (options) {- 19
options = options || {};- 19
this.name = options.name || "appender";- 19
this.pattern = options.pattern || "[{[yyyy-MM-ddTHH:mm:ss:SSS (z)]timeStamp}] {[- 5]levelName} {[-20]name} - {message}";- 19
var level = options.level;- 19
if (options.level && (level = Level.toLevel(level))) {- 3
this.__level = level;}},/*** Appends a message to a log.* <b>This method is abstract and must be implemented in subclasses</b>* @param {Object} event the logging event to log.* @param {Date} event.timeStamp the timeStamp of the event.* @param {comb.logging.Level} level the level of the event.* @param {String} name the name of the logger the event was emitted from.* @param {String} message the message that is being logged.**/append:function (event) {- 1
throw new Error("abstract method");},_canAppend:function (event) {- 75
return !base.isUndefinedOrNull(this.__level) && event.level.isGreaterOrEqualToo(this.__level);},/**@ignore*/setters:{/**@ignore*/level:function (level) {- 57
if (level && level instanceof Level) {- 50
this.__level = level;} else {//try to get the level- 7
level = Level.toLevel(level);- 7
if (level) {- 4
this.__level = level;}}},pattern:function (patt) {- 20
if (base.isString(patt)) {- 20
this.__pattern = patt;}},name:function (name) {- 25
if (base.isString(name)) {- 25
this.__name = name;}}},/**@ignore*/getters:{/**@ignore*/level:function () {- 70
return this.__level;},name:function () {- 90
return this.__name;},pattern:function () {- 3
return this.__pattern;}}},"static":{/**@lends comb.logging.appenders.Appender*//*** Register an appender so it can be used with {@link comb.logging.PropertyConfigurator}** @example** var Appender = comb.logging.appenders.Appender;* comb.define(Appender, {* instance : {* append : function(event){* //log the message* }* }* }).registerType("MyAppender").as(module);** @param {String} type the identifier for your appender type.* @return returns the Appender class for chaining.*/registerType:function (type) {- 5
if (base.isString(type)) {- 5
APPENDER_TYPES[type.toLowerCase()] = this;}- 5
return this;},/*** Acts as a factory for appenders.** @example** var logging = comb.logging,* Logger = logging.Logger,* Appender = logging.appenders.Appender;** var logger = comb.logging.Logger.getLogger("my.logger");* logger.addAppender(Appender.createAppender("consoleAppender"));** @param {String} type the type of appender to create.* @param {Object} [options={}] additional options to pass to the appender.* @return {comb.logging.appenders.Appender} an appender to add to a logger.*/createAppender:function (type, options) {- 14
var caseType = type.toLowerCase();- 14
if (caseType in APPENDER_TYPES) {- 13
return new APPENDER_TYPES[caseType](options);} else {- 1
throw new Error(type + " appender is not registered!");}}}}).as(module);
|
logging/appenders/consoleAppender.js
|
Coverage100.00
SLOC37
LOC17
Missed0
|
- 1
var define = require("../../define.js").define, base = require("../../base"), string = base.string, style = string.style, format = string.format, Appender = require("./appender"), Level = require("../level");/*** @class Appends messages to the console.** @name ConsoleAppender* @augments comb.logging.appenders.Appender* @memberOf comb.logging.appenders*/- 1
define(Appender, {instance:{constructor:function (options) {- 7
options = options || {};- 7
!options.name && (options.name = "consoleAppender");- 7
this._super(arguments, [options]);},append:function (event) {- 6
if (this._canAppend(event)) {- 6
var message = format(this.__pattern, event);- 6
var level = event.level;- 6
if (Level.ERROR.equals(level) || Level.FATAL.equals(level)) {- 2
console.log(style(message, "red"));- 4
} else if (Level.WARN.equals(level)) {- 1
console.log(style(message, "yellow"));- 3
} else if (Level.DEBUG.equals(level)) {- 1
console.log(style(message, "magenta"));- 2
} else if (Level.TRACE.equals(level)) {- 1
console.log(style(message, "cyan"));} else {- 1
console.log(message);}}}}}).registerType("ConsoleAppender").as(module);
|
logging/appenders/fileAppender.js
|
Coverage100.00
SLOC83
LOC22
Missed0
|
- 1
var define = require("../../define.js").define,base = require("../../base"),promise = require("../../promise"),string = base.string,Promise = promise.Promise,PromiseList = promise.PromiseList,style = string.style,format = string.format,Appender = require("./appender"),Level = require("../level"),fs = require("fs");/*** @class Appends messages to a file.** @example* var fileAppender = new comb.logging.appenders.FileAppender({* file : "/var/log/myLog.log"* });*** @name FileAppender* @augments comb.logging.appenders.Appender* @memberOf comb.logging.appenders** @param {Object} [options] options to assign to this Appender* @param {String} [options.name="appender"] the name of this Appender. If you want two of the same type of appender* on a logger it must have a different name.* @param {String} [options.pattern="[{[yyyy-MM-ddTHH:mm:ss:SSS (z)]timeStamp}] {[- 5]levelName} {[-20]name} - {message}"]* <p>Available Options for formatting see {@link comb.string.format} for formatting options</p>* <ul>* <li>timeStamp - the timestamp of the event being logged</li>* <li>level - the {@link comb.logging.Level} of the event</li>* <li>levelName - the name of the level being logged</li>* <li>name - the name of the logger logging the event</li>* <li>message - the message being logged</li>* </ul>* @param {comb.logging.Level|String} [options.level=comb.logging.Level.INFO] the logging level of this appender* <p><b>Note:</b> the level can be different from the logger in the case that you want a particular logger* to only log particular event of a level. For example an appender that only logs errors. BEWARE that if the* appenders level is lower than the logger is will not recieve any messages.</p>** @param {String} [options.file="./log.log"] the file to log events to.* @param {String} [options.encoding="utf8"] the encoding of the file.* @param {Boolean} [options.overwrite=false] if true the log file is overwritten otherwise it is appended to.* @ignoreCode*/- 1
define(Appender, {instance:{constructor:function (options) {- 8
options = options || {};- 8
!options.name && (options.name = "fileAppender");- 8
this.__file = options.file || "./log.log";- 8
this.__encoding = options.encoding || "utf8";- 8
this.__overwrite = options.overwrite || false;- 8
this.__writeStream = options.writeStream || fs.createWriteStream(this.__file, { flags:this.__overwrite ? "w" : 'a', encoding:this.__encoding});- 8
this._super([options]);- 8
this.__pattern += "\n";- 8
base.listenForExit(base.hitch(this, "__onExit"));},__onExit:function () {- 14
var ret = new Promise();- 14
var ws = this.__writeStream;- 14
this.__writeStream = null;- 14
ws.on("close", base.hitch(ret, "callback"));- 14
ws.destroySoon();- 14
return ret.promise();},append:function (event) {- 15
var ws = this.__writeStream;- 15
if (this._canAppend(event) && ws && ws.writable) {- 15
var message = format(this.__pattern, event);- 15
var level = event.level;- 15
ws.write(message);}}}}).registerType("FileAppender").as(module);
|
logging/appenders/index.js
|
Coverage100.00
SLOC11
LOC5
Missed0
|
/**@ignore*/- 1
exports.Appender = require("./appender");/**@ignore*/- 1
exports.ConsoleAppender = require("./consoleAppender");/**@ignore*/- 1
exports.FileAppender = require("./fileAppender");/**@ignore*/- 1
exports.JSONAppender = require("./jsonAppender");/**@ignore*/- 1
exports.RollingFileAppender = require("./rollingFileAppender");
|
logging/appenders/jsonAppender.js
|
Coverage100.00
SLOC85
LOC19
Missed0
|
- 1
var define = require("../../define.js").define,base = require("../../base"),string = base.string,escape = base.regexp.escapeString,FileAppender = require("./fileAppender"),format = string.format,Level = require("../level"),fs = require("fs");/*** @class Appends messages to a file in JSON format. The messages are logged to an array in a JSON file* <b>The file is always overwritten</b>** @example* //example log.json* [* {* "timestamp" : "Wed Jun 08 2011 11:16:20 GMT-0500 (CDT)",* "level" : "INFO",* "name" : "comb",* "message" : "INFO MESSAGE!!!!"* }* ]*** @name JSONAppender* @augments comb.logging.appenders.FileAppender* @memberOf comb.logging.appenders** @param {Object} [options] options to assign to this Appender* @param {String} [options.name="appender"] the name of this Appender. If you want two of the same type of appender* on a logger it must have a different name.* @param {String} [options.pattern="{"timestamp" : "{timeStamp}", "level" : "{levelName}", "name" : "{name}", "message" : "{message}"}"]* <p>Available Options for formatting see {@link comb.string.format} for formatting options</p>* <ul>* <li>timeStamp - the timestamp of the event being logged</li>* <li>level - the {@link comb.logging.Level} of the event</li>* <li>levelName - the name of the level being logged</li>* <li>name - the name of the logger logging the event</li>* <li>message - the message being logged</li>* </ul>* @param {comb.logging.Level|String} [options.level=comb.logging.Level.INFO] the logging level of this appender* <p><b>Note:</b> the level can be different from the logger in the case that you want a particular logger* to only log particular event of a level. For example an appender that only logs errors. BEWARE that if the* appenders level is lower than the logger is will not recieve any messages.</p>** @param {String} [options.file="./log.json"] the file to log events to.* @param {String} [options.encoding="utf8"] the encoding of the file.** @ignoreCode*/- 1
define(FileAppender, {instance:{constructor:function (options) {- 5
options = options || {};- 5
this.name = options.name || "JSONAppender";- 5
this.__count = 0;- 5
this.__file = options.file || "./log.json";- 5
this.__encoding = options.encoding || "utf8";- 5
this.__writeStream = options.writeStream || fs.createWriteStream(this.__file, { flags:"w", encoding:this.__encoding});- 5
this.__writeStream.write("[\n");- 5
this.level = options.level;//explicit overwrite of patter- 5
this.__pattern = '{"timestamp" : "{timeStamp}", "level" : "{levelName}", "name" : "{name}", "message" : "{message}"}';- 5
base.listenForExit(base.hitch(this, "__onExit"));},append:function (event) {- 6
if (this._canAppend(event)) {- 6
event.message = event.message.replace(/\n+/g, "\\n");- 6
var message = (this.__count ? ",\n" : "\n") + format(this.__pattern, event);- 6
this.__writeStream.write(message);- 6
this.__count++;}},__onExit:function () {- 5
this.__writeStream.write("]");- 5
this._super(arguments);}}}).registerType("JSONAppender").as(module);
|
logging/appenders/rollingFileAppender.js
|
Coverage100.00
SLOC211
LOC79
Missed0
|
- 1
var define = require("../../define.js").define,promise = require("../../promise"),Promise = promise.Promise,PromiseList = promise.PromiseList,base = require("../../base"),hitch = base.hitch,string = base.string,escape = base.regexp.escapeString,style = string.style,format = string.format,FileAppender = require("./fileAppender"),Level = require("../level"),fs = require("fs"),path = require("path");- 1
var conversion = {MB:1048576,KB:1024,GB:1073741824};- 1
var DEFAULT_SIZE = "10MB";- 1
var convertToBytes = function (str) {- 3
var ret = DEFAULT_SIZE;- 3
var match = str.match(/(\d+)(MB|KB|GB)$/);- 3
if (match && match.length == 3) {- 3
var size = parseInt(match[1], 10);- 3
ret = size * conversion[match[2]];}- 3
return ret;}/*** @class Appends messages to a file. Rolls files over when a size limit has been reached. Once the max file size has* been reached it is rolled over to a file called <logName>.log.n where n is a number.* </br></br>* <p>Example. RollingFileAppender is current writing to myLog.log, the log reaches is max size to it is* renamed to myLog.log.1 and a new myLog.log is created.</p>* </br>* If maxBackupIndex is reached then the log at that index is deleted. If maxBackupIndex is set to 0 then no log is* rolled over.</p>** @name RollingFileAppender* @augments comb.logging.appenders.FileAppender* @memberOf comb.logging.appenders** @param {Object} [options] options to assign to this Appender* @param {String} [options.name="appender"] the name of this Appender. If you want two of the same type of appender* on a logger it must have a different name.* @param {String} [options.pattern="[{[yyyy-MM-ddTHH:mm:ss:SSS (z)]timeStamp}] {[- 5]levelName} {[-20]name} - {message}"]* <p>Available Options for formatting see {@link comb.string.format} for formatting options</p>* <ul>* <li>timeStamp - the timestamp of the event being logged</li>* <li>level - the {@link comb.logging.Level} of the event</li>* <li>levelName - the name of the level being logged</li>* <li>name - the name of the logger logging the event</li>* <li>message - the message being logged</li>* </ul>* @param {comb.logging.Level|String} [options.level=comb.logging.Level.INFO] the logging level of this appender* <p><b>Note:</b> the level can be different from the logger in the case that you want a particular logger* to only log particular event of a level. For example an appender that only logs errors. BEWARE that if the* appenders level is lower than the logger is will not recieve any messages.</p>** @param {String} [options.file="./log.log"] the file to log events to.* @param {String} [options.encoding="utf8"] the encoding of the file.* @param {Boolean} [options.overwrite=false] if true the log file is overwritten otherwise it is appended to.* @param {String} [options.maxSize="10MB"] the maxSize of a file. Valid options include "KB", "MB", or "GB"** <pre class="code">* maxSize = "100MB"* //or* maxSize = "100KB"* //or* maxSize = "1GB"* </pre>** @param {Number} [options.maxBackupIndex=10] the maximum number of files to rollOver.*/- 1
define(FileAppender, {instance:{__watching:false,constructor:function (options) {- 3
options = options || {};- 3
this.maxSize = options.maxSize || DEFAULT_SIZE;- 3
!options.name && (options.name = "rollingFileAppender");- 3
this.maxBackupIndex = options.maxBackupIndex || 10;- 3
this.__queue = [];- 3
this.__inRollover = false;- 3
this._super([options]);},__startCheck:function () {- 1
if (!this.__watching) {- 1
this.__watching = true;- 1
fs.watchFile(this.__file, hitch(this, "__checkFile"));- 1
fs.stat(this.__file, hitch(this, function (err, stat) {- 1
this.__checkFile(stat);}));}},__checkFile:function (stats) {- 5
var ret = new Promise();- 5
if (!this.__inRollover) {- 3
if (stats.size >= this.maxSize) {- 2
if (this.maxBackupIndex > 0) {- 1
this.__inRollover = true;- 1
this.__onExit().chain(hitch(this, "__rollover")).then(hitch(this, function () {- 1
var ws = fs.createWriteStream(this.__file, { flags:"w", encoding:this.__encoding});- 1
ws.on("open", hitch(this, function () {- 1
this.__writeStream = ws;- 1
this.__inRollover = false;- 1
this.__checkQueue();- 1
ret.callback();}));}), hitch(ret, "errback", new Error("comb.logging.appenders.RollingFileAppender : error rolling over files")));} else {- 1
this.__writeStream = fs.createWriteStream(this.__file, { flags:"w", encoding:this.__encoding});- 1
ret.callback();}} else {- 1
ret.callback();}} else {- 2
ret.callback();}- 5
return ret.promise();},append:function (event) {- 12
if (this._canAppend(event)) {- 12
!this.__watching && this.__startCheck();- 12
var ws = this.__writeStream;- 12
if (!this.__inRollover && ws && ws.writable) {- 9
this._super(arguments);} else {- 3
this.__queue.push(event);}}},__checkQueue:function () {- 1
this.__queue.forEach(this.append, this);- 1
this.__queue.length = 0;},__rollover:function () {- 1
var ret = new Promise(), file = this.__file;- 1
var dir = path.dirname(file), baseName = new RegExp("(" + escape(path.basename(path.basename(file))) + ")(?:\\.(\\d*))*");- 1
fs.readdir(dir, hitch(this, function (err, files) {- 1
files = files.filter(function (f) {- 5
var match = f.match(baseName);- 5
if (match) {- 4
return true;} else {- 1
return false;}});- 1
files = files.sort(function (a, b) {- 6
var ret = 0;- 6
if (a > b) {- 3
ret = 0;- 3
} else if (a < b) {- 3
ret = 1;}- 6
return ret;});- 1
var count = files.length, i = 0;- 1
var checkFile = hitch(this, function () {- 5
if (count > 0) {- 4
var f = dir + "/" + files[i++];- 4
if (count > this.maxBackupIndex) {//drop the file;- 1
count--;- 1
fs.unlink(f, function (err) {- 1
err ? ret.errback(err) : checkFile();});} else {//rename the file- 3
var rn = this.__file + "." + count--;- 3
fs.rename(f, rn, function (err) {- 3
err ? ret.errback(err) : checkFile();});}} else {- 1
ret.callback();}});- 1
checkFile();}));- 1
return ret.promise();},getters:{maxSize:function () {- 3
return this.__maxSize;}},setters:{maxSize:function (size) {- 3
this.__maxSize = size ? convertToBytes(size) : DEFAULT_SIZE;}}}}).registerType("RollingFileAppender").as(module);
|
logging/config.js
|
Coverage100.00
SLOC193
LOC38
Missed0
|
- 1
var define = require("../define.js").define, base = require("../base"), fs = require('fs'), Appender = require("./appenders/appender.js");- 1
var logging, Logger, Level, appenders;- 1
var parseProperties = function (properties) {- 4
for (var i in properties) {- 4
var logger = Logger.getLogger(i);- 4
var props = properties[i], level = props.level, appenderArr = props.appenders;- 4
if (level) {- 4
level = Level.toLevel(level);- 4
if (level) {- 4
logger.level = level;}}- 4
if (appenderArr && base.isArray(appenderArr)) {- 4
for (var j = appenderArr.length - 1; j >= 0; j--) {- 14
var appenderProps = base.merge({}, appenderArr[j]), type = appenderProps.type;- 14
appenderProps.type = null;- 14
if (type) {- 12
logger.addAppender(type, appenderProps);}}}}};/*** @class default configurator for logging** @name BasicConfigurator* @memberOf comb.logging* @ignoreCode**/- 1
var BasicConfigurator = (exports.BasicConfigurator = define(null, {instance: {/**@lends comb.logging.BasicConfigurator.prototype*/constructor: function () {- 6
if (!Logger) {- 1
logging = require("./index").logging;- 1
Logger = logging.Logger;- 1
Level = logging.Level;- 1
appenders = logging.appenders;}},/*** Configure logging.** @param {comb.logging.Appender} [appender=null] appender to add to the root logger, by default a console logger is added.*/configure: function (appender) {- 4
var rootLogger = Logger.getRootLogger();- 4
rootLogger.removeAllAppenders();- 4
if (base.isInstanceOf(appender, appenders.Appender)) {- 2
rootLogger.addAppender(appender);} else {- 2
rootLogger.addAppender(new appenders.ConsoleAppender());}}}}));/*** @class Configures comb.Logger with the properties or properties contained within a file** @example** var propertyConfigurator = new comb.logging.PropertyConfigurator();** propertyConfigurator.configure("/location/of/combLogger.json");** //or** var config = {* "my.logger" : {* level : "INFO",* appenders : [* {* //default file appender* type : "FileAppender",* file : "/var/log/myApp.log",* },* {* //default JSON appender* type : "JSONAppender",* file : "/var/log/myApp.JSON",* },* {* type : "FileAppender",* //override default patter* pattern : "{[EEEE, MMMM dd, yyyy h:m a]timeStamp} {[5]level}"* + " {[- 5]levelName} {[-20]name} : {message}",* //location of my log file* file : "/var/log/myApp-errors.log",* //override name so it will get added to the log* name : "errorFileAppender",* //overwrite each time* overwrite : true,* //explicity set the appender to only accept errors* level : "ERROR"* },* {* type : "JSONAppender",* file : "/var/log/myApp-error.json",* //explicity set the appender to only accept errors* level : "ERROR"* }* ]* }* //repeat for more loggers** propertyConfigurator.configure(config);* }** @name PropertyConfigurator* @augments comb.logging.BasicConfigurator* @memberOf comb.logging* @ignoreCode**/- 1
exports.PropertyConfigurator = define(BasicConfigurator, {instance: {/**@lends comb.logging.PropertyConfigurator.prototype*//*** Call to configure logging** @example** //Example configuration* {* "my.logger" : {* level : "INFO",* appenders : [* {* //default file appender* type : "FileAppender",* file : "/var/log/myApp.log",* },* {* //default JSON appender* type : "JSONAppender",* file : "/var/log/myApp.JSON",* },* {* type : "FileAppender",* //override default patter* pattern : "{[EEEE, MMMM dd, yyyy h:m a]timeStamp} {[5]level}"* + " {[- 5]levelName} {[-20]name} : {message}",* //location of my log file* file : "/var/log/myApp-errors.log",* //override name so it will get added to the log* name : "errorFileAppender",* //overwrite each time* overwrite : true,* //explicity set the appender to only accept errors* level : "ERROR"* },* {* type : "JSONAppender",* file : "/var/log/myApp-error.json",* //explicity set the appender to only accept errors* level : "ERROR"* }* ]* }** @param {Object|String} properties Object containing configuration or string containing a file name with the configuration.*/configure: function (properties) {- 6
var rootLogger = Logger.getRootLogger();- 6
rootLogger.removeAllAppenders();- 6
if (base.isHash(properties)) {- 2
parseProperties(base.deepMerge({}, properties));} else {- 4
fs.readFile(properties, function (err, res) {- 4
if (err) {- 1
throw err;} else {- 3
try {- 3
parseProperties(JSON.parse(res));} catch (e) {- 1
throw e;}}});}}}});
|
logging/level.js
|
Coverage100.00
SLOC188
LOC33
Missed0
|
- 1
var define = require("../define.js").define, base = require("../base");- 1
var LEVELS = {ALL:-100000,DEBUG:1,TRACE:2,INFO:3,WARN:4,ERROR:5,FATAL:6,OFF:100000};- 1
var LEVELS_REVERSE = {"-100000":"ALL","1":"DEBUG","2":"TRACE","3":"INFO","4":"WARN","5":"ERROR","6":"FATAL","100000":"OFF"};/*** @class Level class used to describe logging levels. The levels determine what types of events are logged to the appenders* for example the if Level.ALL is used then all event will be logged, however if Level.INFO was used then <b>ONLY</b>* INFO, WARN, ERROR, and FATAL events will be logged. To turn off logging for a logger use Level.OFF.** <p><b>Not typically instantiated directly, but through staticly defined levels</b></p>* @example* //Levels in ascending order* comb.logging.Level.ALL* comb.logging.Level.DEBUG* comb.logging.Level.TRACE* comb.logging.Level.INFO* comb.logging.Level.WARN* comb.logging.Level.ERROR* comb.logging.Level.FATAL* comb.logging.Level.OFF** //or* Level.getLevel("INFO");** @name Level* @memberOf comb.logging** @property {Number} level the numerical representation of this level.* @property {String} name the name of level.* @ignoreCode*/- 1
var Level = (exports = module.exports = define(null, {instance:{/**@lends comb.logging.Level.prototype*/constructor:function (level, name) {- 9
this.level = level;- 9
this.name = name;},/*** Determing if this level is >= another level* @param {comb.logging.Level} level the level to test against** @returns {Boolean} true if this is >= false otherwise.*/isGreaterOrEqualToo:function (level) {- 288
var ret = false;- 288
if (level && base.isNumber(level.level)) {- 288
if (this.level >= level.level) {- 187
ret = true;}}- 288
return ret;},/*** Determing if this level is equal to another level based off of the numerical rank.** @param {comb.logging.Level} level the level to compare** @returns {Boolean} true if this is equal to that false otherwise.*/equals:function (level) {- 145
return level.level == this.level;}},static:{/**@lends comb.logging.Level*//*** Converts a numerical or string representation of a level, if a default level is provided,* then if a level cannot be determined then the default level is used.** @param {Number|String|comb.logging.Level} level the level to try to convert* @param {comb.logging.Level} [defaultLevel] default level to use if one cannot be determined,** @returns {comb.logging.Level|null} returns a level if one can be determined null otherwise.*/toLevel:function (level, defaultLevel) {- 193
var ret = null;- 193
var args = base.argsToArray(arguments);- 193
if (args.length === 1) {- 191
var level = args[0];- 191
if (base.isNumber(level)) {- 11
var strLevel = LEVELS_REVERSE[level];- 11
ret = Level[strLevel];- 180
} else if (base.isString(level)) {- 48
ret = Level[level.toUpperCase()];} else {- 132
ret = level;}} else {- 2
ret = (Level.toLevel(args[0]) || args[1]);}- 193
return ret;},/*** Adds a new level to the Level object.** @example** logger = Logger.getLogger("my.logger");** //create the custom level* Level.addLevel("custom_Level", 20);** //now set the level on a logger* logger.level = Level.CUSTOM_LEVEL;** @param {string} label the label of the level, <b>Note:</b> the label will be coverted to uppercase.* @param {number} level the level of the level** @return {undefined|comb.logging.Level} the level that was created.**/addLevel:function (label, level) {- 1
var ret;- 1
if (base.isString(label) && base.isNumber(level)) {- 1
label = label.toUpperCase();- 1
LEVELS_REVERSE[level] = label;- 1
LEVELS[label] = level;- 1
ret = (this[label] = new Level(level, label));}- 1
return ret;},/*** Level to allow logging of all events.*/ALL:null,/*** Logs only events debug or greater.*/DEBUG:null,/*** Like debug but provides a finer level of detail*/TRACE:null,/*** Only info, or error related events*/INFO:null,/*** Only warn or error related events*/WARN:null,/*** Error or fatal events*/ERROR:null,/*** Only fatal events*/FATAL:null,/*** No events will be logged.*/OFF:null}}));- 1
for (var i in LEVELS_REVERSE) {- 8
Level[LEVELS_REVERSE[i]] = new Level(parseInt(i, 10), LEVELS_REVERSE[i]);}
|
plugins/Broadcaster.js
|
Coverage100.00
SLOC113
LOC26
Missed0
|
- 1
var func = require("../base/functions"),define = require("../define").define;- 1
var Broadcaster = define(null, {instance : {/** @lends comb.plugins.Broadcaster.prototype *//*** Plugin to allow a class to easily broadcast events** @example** var Mammal = define(comb.plugins.Broadcaster, {* instance : {** constructor: function(options) {* options = options || {};* this._super(arguments);* this._type = options.type || "mammal";* },** speak : function() {* var str = "A mammal of type " + this._type + " sounds like";* this.broadcast("speak", str);* this.onSpeak(str);* return str;* },** onSpeak : function(){}* }* });*** var m = new Mammal({color : "gold"});* m.listen("speak", function(str){* //called back from the broadcast event* console.log(str);* });* m.speak();** @constructs*/constructor : function() {- 2
this.__listeners = {};},/*** Broadcasts an event from an object** @param name the name of the event to broadcast* @param {Object|String|Function|Date|Number} [args] variable number of arguments to pass to listeners, can be anything*/broadcast : function(topic, args) {- 2
var args = Array.prototype.slice.call(arguments, 0), topic = args.shift();- 2
if (topic && topic in this.__listeners) {- 2
var list = this.__listeners[topic], i = list.length - 1;- 2
while (i >= 0) {- 2
list[i--].cb.apply(this, args);}}},/*** Listens to a broadcasted event* Simimlar to {@link comb.listen}** @param {String} topic the topic to listen to* @param {Function} callback the function to callback on event publish** @returns {Array} handle to disconnect a topic*/listen : function(topic, callback) {- 3
if (!func.isFunction(callback)) throw new Error("callback must be a function");- 3
var handle = {topic : topic,cb : callback};- 3
var list = this.__listeners[topic];- 3
if (!list) {- 2
list = (this.__listeners[topic] = [handle]);- 2
handle.pos = 0;} else {- 1
handle.pos = list.push(handle);}- 3
return handle;},/*** Disconnects a listener* Similar to {@link comb.unListen}** @param handle disconnect a handle returned from Broadcaster.listen*/unListen : function(handle) {- 1
if (handle) {- 1
var topic = handle.topic;- 1
if (topic in this.__listeners) {- 1
var listeners = this.__listeners, list = listeners[topic];- 1
if (list) {- 1
for (var i = list.length - 1; i >= 0; i--) {- 1
if (list[i] == handle) {- 1
list.splice(i, 1);- 1
break;}}}}}}}});- 1
exports = module.exports = Broadcaster;
|
plugins/Middleware.js
|
Coverage100.00
SLOC212
LOC40
Missed0
|
- 1
var func = require("../base/functions"),obj = require("../base/object"),Promise = require("../promise").Promise,define = require("../define").define;- 1
var Middleware = define(null, {instance: {/** @lends comb.plugins.Middleware.prototype */__hooks: {pre: {}, post: {}},/*** @class Plugin to enable middleware on a class** @example** var Mammal = define(comb.plugins.Middleware, {* instance : {** constructor: function(options) {* options = options || {};* this.super(arguments);* this._type = options.type || "mammal";* },** speak : function() {* var ret = new comb.Promise();* this._hook("pre", "speak")* .then(comb.hitch(this, "_hook", "post", "speak"), hitch(ret, "errback"))* .then(comb.hitch(ret, "callback"), comb.hitch(ret, "errback"));* return ret;* }* }*});** Mammal.pre('speak', function(next){* //do something meaningful* next();* });* var m = new Mammal({color : "gold"});* m.speak();** @constructs*/constructor: function () {- 6
this.__hooks = obj.merge({}, this.__hooks);- 6
this._super(arguments);},/*** <p>Protected!</p>** <p>Call to initiate middleware for the topic</p>* <p><b>NOTE:</b> this function takes a variable number of arguments* whatever comes after the op param will be passed into* the listening function, with the last argument to the listenting* function being the next function</p>*** @public* @param {"pre"|"post"} state the state in which the hook should be called* @param {String} op the operation that is being acted upong* @param args arguments to be passed into the listening functions.* @returns {comb.Promise} a promise to use after middleware chain completes**/_hook: function (state, op, args) {- 11
args = args || [];- 11
var promise = new Promise();- 11
var funcs, length;- 11
if (this.__hooks[state] && (funcs = this.__hooks[state][op]) != null && (length = funcs.length) > 0) {- 7
var count = 0;- 7
var next = func.hitch(this, function (err) {- 15
if (err) {- 1
promise.errback(err);} else {- 14
setImmediate(func.hitch(this, function () {//if Ive looped through all of them callback- 14
if (count == length) {- 6
promise.callback();} else {//call next- 8
var nextArgs = args.slice(0);- 8
nextArgs.unshift(next);- 8
funcs[count++].apply(this, nextArgs);}}));}});- 7
next();} else {- 4
promise.callback();}- 11
return promise.promise();},/*** Use to listen to before an event occurred i.e. pre save** <b>NOTE:</b></br>* <ul>* <li>You must call next in order for the middleware chain to complete</li>* <li>This connects to events on the instance of an object, not all instances!</li>* <li>Hooks are called in the order they are received!</li>* <li> When connecting your callback will be called in the scope of the class</br>if you want a certain scope use {@link comb.hitch}</li>* </ul>** @example* instance.pre("save", function(args,...., next){* //do something...* //you have to call next!!!!!* next();* });** */pre: function (fun, callback) {- 1
var hook = this.__hooks.pre[fun];- 1
if (!hook) {- 1
hook = this.__hooks.pre[fun] = [];}- 1
hook.push(callback);},/*** <p>Use to listen to after an event has occurred i.e. post save</p>* <b>NOTE:</b></br>* <ul>* <li>You must call next in order for the middleware chain to complete</li>* <li>This connects to events on the instance of an object, NOT all instances!</li>* <li>Hooks are called in the order they are received!</li>* <li>When connecting your callback will be called in the scope of the class</br>if you want a certain scope use {@link comb.hitch}</li>* </ul>* @example** instance.post("save", function(next){* //do something...* //you have to call next!!!!!* next();* });* */post: function (fun, callback) {- 1
var hook = this.__hooks.post[fun];//if I havent initialized it create it;- 1
if (hook == undefined) {- 1
hook = this.__hooks.post[fun] = [];}- 1
hook.push(callback);}},static: {/** @lends comb.plugins.Middleware *//***<p> Use to listen to after an event has occurred i.e. post save</p>** <b>NOTE:</b></br>* <ul>* <li>You must call next in order for the middleware chain to complete</li>* <li>This connects to events on ALL instances of an object</li>* <li>Hooks are called in the order they are received!</li>* <li>When connecting your callback will be called in the scope of the class</br>if you want a certain scope use {@link comb.hitch}</li>* </ul>** @example* Class.pre("save", function(next){* ...* //you must call next* });* */pre: function (name, cb) {- 2
var hooks = this.prototype.__hooks;- 2
var hook = hooks.pre[name];- 2
if (!hook) {- 1
hook = hooks.pre[name] = [];}- 2
hook.push(cb);},/***<p>Use to listen to after an event has occurred i.e. post save</p>**<b>NOTE:</b></br>* <ul>* <li>You must call next in order for the middleware chain to complete</li>* <li>This connects to events on ALL instances of an object</li>* <li>Hooks are called in the order they are received!</li>* <li>When connecting your callback will be called in the scope of the class</br>if you want a certain scope use {@link comb.hitch}</li>* </ul>** @example* Class.post("save", function(next){* ...* //you must call next* });* */post: function (name, cb) {- 1
var hooks = this.prototype.__hooks;- 1
var hook = hooks.post[name];- 1
if (!hook) {- 1
hook = hooks.post[name] = [];}- 1
hook.push(cb);}}});- 1
module.exports = exports = Middleware;
|
plugins/index.js
|
Coverage100.00
SLOC6
LOC2
Missed0
|
- 1
var comb = exports;/**@namespace plugins for classes using {@link comb.define}*/- 1
comb.plugins = {Broadcaster : require("./Broadcaster"),Middleware : require("./Middleware")};