Merge pull request #271 from hybridgroup/feature/replace-lodash

Replace Lodash
This commit is contained in:
Adrian Zankich 2015-02-24 10:08:06 -08:00
commit 3e65e2027e
11 changed files with 559 additions and 87 deletions

View File

@ -10,7 +10,7 @@
var Basestar = require("./basestar"),
Utils = require("./utils"),
_ = require("./lodash");
_ = require("./utils/helpers");
// Public: Creates a new Adaptor
//
@ -34,12 +34,10 @@ var Adaptor = module.exports = function Adaptor(opts) {
// misc. details provided in args hash
this.details = {};
_.forEach(opts, function(opt, name) {
if (_.include(["robot", "name", "adaptor", "events"], name)) {
return;
_.each(opts, function(opt, name) {
if (!~["robot", "name", "adaptor", "events"].indexOf(name)) {
this.details[name] = opt;
}
this.details[name] = opt;
}, this);
};

View File

@ -10,7 +10,8 @@
var EventEmitter = require("events").EventEmitter;
var Utils = require("./utils");
var Utils = require("./utils"),
_ = require("./utils/helpers");
// Basestar is a base class to be used when writing external Cylon adaptors and
// drivers. It provides some useful base methods and functionality
@ -83,7 +84,7 @@ Basestar.prototype.defineDriverEvent = function(opts) {
};
Basestar.prototype._proxyEvents = function(opts, source, target) {
opts = (typeof opts === "string") ? { eventName: opts } : opts;
opts = _.isString(opts) ? { eventName: opts } : opts;
opts.source = source;
opts.target = target;

View File

@ -14,7 +14,7 @@ var Logger = require("./logger"),
Robot = require("./robot"),
Config = require("./config"),
Utils = require("./utils"),
_ = require("./lodash");
_ = require("./utils/helpers");
var EventEmitter = require("events").EventEmitter;
@ -103,7 +103,7 @@ Cylon.api = function api(Server, opts) {
];
}
_.each(messages, function(str) { Logger.error(str); });
_.each(messages, _.arity(Logger.error, 1));
return;
} else {
throw e;
@ -121,7 +121,7 @@ Cylon.api = function api(Server, opts) {
//
// Returns nothing
Cylon.start = function start() {
var starters = _.map(this.robots, "start");
var starters = _.pluck(this.robots, "start");
Async.parallel(starters, function() {
var mode = Utils.fetch(Config, "workMode", "async");
@ -138,13 +138,15 @@ Cylon.start = function start() {
//
// Returns the current config
Cylon.config = function(opts) {
var logChanges = (opts.logging && !_.isEqual(Config.logging, opts.logging));
var loggingChanged = (
opts.logging && Config.logging !== _.extend(Config.logging, opts.logging)
);
if (_.isObject(opts) && !_.isArray(opts)) {
Config = _.merge(Config, opts);
if (_.isObject(opts)) {
Config = _.extend(Config, opts);
}
if (logChanges) {
if (loggingChanged) {
Logger.setup();
}
@ -159,7 +161,7 @@ Cylon.config = function(opts) {
Cylon.halt = function halt(callback) {
callback = callback || function() {};
var fns = _.map(this.robots, "halt");
var fns = _.pluck(this.robots, "halt");
// if robots can"t shut down quickly enough, forcefully self-terminate
var timeout = Config.haltTimeout || 3000;
@ -171,7 +173,7 @@ Cylon.halt = function halt(callback) {
Cylon.toJSON = function() {
return {
robots: _.invoke(this.robots, "toJSON"),
commands: _.keys(this.commands),
commands: Object.keys(this.commands),
events: this.events
};
};

View File

@ -10,7 +10,7 @@
var Basestar = require("./basestar"),
Utils = require("./utils"),
_ = require("./lodash");
_ = require("./utils/helpers");
// Public: Creates a new Driver
//
@ -36,12 +36,12 @@ var Driver = module.exports = function Driver(opts) {
this.details = {};
_.forEach(opts, function(opt, name) {
if (_.include(["robot", "name", "connection", "driver", "events"], name)) {
return;
}
_.each(opts, function(opt, name) {
var banned = ["robot", "name", "connection", "driver", "events"];
this.details[name] = opt;
if (!~banned.indexOf(name)) {
this.details[name] = opt;
}
}, this);
};
@ -54,7 +54,7 @@ Driver.prototype.setupCommands = function(commands, proxy) {
Utils.proxyFunctionsToObject(commands, proxy, this);
_.forEach(commands, function(command) {
commands.forEach(function(command) {
var snake_case = command.replace(/[A-Z]+/g, function(match) {
if (match.length > 1) {
match = match.replace(/[A-Z]$/, function(m) {
@ -74,7 +74,7 @@ Driver.prototype.toJSON = function() {
name: this.name,
driver: this.constructor.name || this.name,
connection: this.connection.name,
commands: _.keys(this.commands),
commands: Object.keys(this.commands),
events: this.events,
details: this.details
};

View File

@ -10,7 +10,7 @@
var Registry = require("./registry"),
Config = require("./config"),
_ = require("./lodash");
_ = require("./utils/helpers");
function testMode() {
return process.env.NODE_ENV === "test" && Config.testMode;
@ -33,7 +33,7 @@ module.exports = function Initializer(type, opts) {
var obj = mod[type](opts);
_.forIn(obj, function(prop, name) {
_.each(obj, function(prop, name) {
if (name === "constructor") {
return;
}
@ -46,7 +46,7 @@ module.exports = function Initializer(type, opts) {
if (testMode()) {
var test = Registry.findBy(type, "test")[type](opts);
_.forIn(obj, function(prop, name) {
_.each(obj, function(prop, name) {
if (_.isFunction(prop) && !test[name]) {
test[name] = function() { return true; };
}

View File

@ -1,26 +0,0 @@
/**
* @license
* Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
* Build: `lodash compat exports="node" include="bindAll,each,first,forEach,forIn,forOwn,include,invoke,isArray,isEqual,isFunction,isObject,isString,keys,map,merge,result,values" --minify --output ./lib/lodash.js`
*/
;(function(){function n(n,t,r){r=(r||0)-1;for(var e=n?n.length:0;++r<e;)if(n[r]===t)return r;return-1}function t(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function r(n){n.length=0,L.length<N&&L.push(n)}function e(n,t,r){t||(t=0),typeof r=="undefined"&&(r=n?n.length:0);var e=-1;r=r-t||0;for(var o=Array(0>r?0:r);++e<r;)o[e]=n[t+e];return o}function o(){}function u(n){function t(){if(o){var n=e(o);pt.apply(n,arguments)}if(this instanceof t){var a=f(r.prototype),n=r.apply(a,n||arguments);
return j(n)?n:a}return r.apply(u,n||arguments)}var r=n[0],o=n[2],u=n[4];return wt(t,n),t}function f(n){return j(n)?ht(n):{}}function a(n,t,r){if(typeof n!="function")return P;if(typeof t=="undefined"||!("prototype"in n))return n;var e=n.__bindData__;if(typeof e=="undefined"&&(_t.funcNames&&(e=!n.name),e=e||!_t.funcDecomp,!e)){var o=ct.call(n);_t.funcNames||(e=!R.test(o)),e||(e=T.test(o),wt(n,e))}if(false===e||true!==e&&1&e[1])return n;switch(r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)
};case 3:return function(r,e,o){return n.call(t,r,e,o)};case 4:return function(r,e,o,u){return n.call(t,r,e,o,u)}}return S(n,t)}function i(n){function t(){var n=s?c:this;if(u){var h=e(u);pt.apply(h,arguments)}return(a||g)&&(h||(h=e(arguments)),a&&pt.apply(h,a),g&&h.length<l)?(o|=16,i([r,y?o:-4&o,h,null,c,l])):(h||(h=arguments),p&&(r=n[v]),this instanceof t?(n=f(r.prototype),h=r.apply(n,h),j(h)?h:n):r.apply(n,h))}var r=n[0],o=n[1],u=n[2],a=n[3],c=n[4],l=n[5],s=1&o,p=2&o,g=4&o,y=8&o,v=r;return wt(t,n),t
}function c(n,t,r,e){e=(e||0)-1;for(var o=n?n.length:0,u=[];++e<o;){var f=n[e];if(f&&typeof f=="object"&&typeof f.length=="number"&&(Et(f)||b(f))){t||(f=c(f,t,r));var a=-1,i=f.length,l=u.length;for(u.length+=i;++a<i;)u[l++]=f[a]}else r||u.push(f)}return u}function l(n,e,o,u,f,a){if(o){var i=o(n,e);if(typeof i!="undefined")return!!i}if(n===e)return 0!==n||1/n==1/e;if(n===n&&!(n&&X[typeof n]||e&&X[typeof e]))return false;if(null==n||null==e)return n===e;var c=at.call(n),s=at.call(e);if(c==$&&(c=V),s==$&&(s=V),c!=s)return false;
switch(c){case z:case G:return+n==+e;case M:return n!=+n?e!=+e:0==n?1/n==1/e:n==+e;case W:case H:return n==e+""}if(s=c==q,!s){var p=st.call(n,"__wrapped__"),g=st.call(e,"__wrapped__");if(p||g)return l(p?n.__wrapped__:n,g?e.__wrapped__:e,o,u,f,a);if(c!=V||!_t.nodeClass&&(t(n)||t(e)))return false;if(c=!_t.argsObject&&b(n)?Object:n.constructor,p=!_t.argsObject&&b(e)?Object:e.constructor,c!=p&&!(d(c)&&c instanceof c&&d(p)&&p instanceof p)&&"constructor"in n&&"constructor"in e)return false}for(c=!f,f||(f=L.pop()||[]),a||(a=L.pop()||[]),p=f.length;p--;)if(f[p]==n)return a[p]==e;
var y=0,i=true;if(f.push(n),a.push(e),s){if(p=n.length,y=e.length,(i=y==p)||u)for(;y--;)if(s=p,g=e[y],u)for(;s--&&!(i=l(n[s],g,o,u,f,a)););else if(!(i=l(n[y],g,o,u,f,a)))break}else Ct(e,function(t,r,e){return st.call(e,r)?(y++,i=st.call(n,r)&&l(n[r],t,o,u,f,a)):void 0}),i&&!u&&Ct(n,function(n,t,r){return st.call(r,t)?i=-1<--y:void 0});return f.pop(),a.pop(),c&&(r(f),r(a)),i}function s(n,t,r,e,o){(Et(t)?w:St)(t,function(t,u){var f,a,i=t,c=n[u];if(t&&((a=Et(t))||Pt(t))){for(i=e.length;i--;)if(f=e[i]==t){c=o[i];
break}if(!f){var l;r&&(i=r(c,t),l=typeof i!="undefined")&&(c=i),l||(c=a?Et(c)?c:[]:Pt(c)?c:{}),e.push(t),o.push(c),l||s(c,t,r,e,o)}}else r&&(i=r(c,t),typeof i=="undefined"&&(i=t)),typeof i!="undefined"&&(c=i);n[u]=c})}function p(n,t,r,o,f,a){var c=1&t,l=4&t,s=16&t,g=32&t;if(!(2&t||d(n)))throw new TypeError;s&&!r.length&&(t&=-17,s=r=false),g&&!o.length&&(t&=-33,g=o=false);var y=n&&n.__bindData__;return y&&true!==y?(y=e(y),y[2]&&(y[2]=e(y[2])),y[3]&&(y[3]=e(y[3])),!c||1&y[1]||(y[4]=f),!c&&1&y[1]&&(t|=8),!l||4&y[1]||(y[5]=a),s&&pt.apply(y[2]||(y[2]=[]),r),g&&yt.apply(y[3]||(y[3]=[]),o),y[1]|=t,p.apply(null,y)):(1==t||17===t?u:i)([n,t,r,o,f,a])
}function g(){U.h=K,U.b=U.c=U.g=U.i="",U.e="t",U.j=true;for(var n,t=0;n=arguments[t];t++)for(var r in n)U[r]=n[r];t=U.a,U.d=/^[^,]+/.exec(t)[0],n=Function,t="return function("+t+"){",r=U;var e="var n,t="+r.d+",E="+r.e+";if(!t)return E;"+r.i+";";r.b?(e+="var u=t.length;n=-1;if("+r.b+"){",_t.unindexedChars&&(e+="if(s(t)){t=t.split('')}"),e+="while(++n<u){"+r.g+";}}else{"):_t.nonEnumArgs&&(e+="var u=t.length;n=-1;if(u&&p(t)){while(++n<u){n+='';"+r.g+";}}else{"),_t.enumPrototypes&&(e+="var G=typeof t=='function';"),_t.enumErrorProps&&(e+="var F=t===k||t instanceof Error;");
var o=[];if(_t.enumPrototypes&&o.push('!(G&&n=="prototype")'),_t.enumErrorProps&&o.push('!(F&&(n=="message"||n=="name"))'),r.j&&r.f)e+="var C=-1,D=B[typeof t]&&v(t),u=D?D.length:0;while(++C<u){n=D[C];",o.length&&(e+="if("+o.join("&&")+"){"),e+=r.g+";",o.length&&(e+="}"),e+="}";else if(e+="for(n in t){",r.j&&o.push("m.call(t, n)"),o.length&&(e+="if("+o.join("&&")+"){"),e+=r.g+";",o.length&&(e+="}"),e+="}",_t.nonEnumShadows){for(e+="if(t!==A){var i=t.constructor,r=t===(i&&i.prototype),f=t===J?I:t===k?j:L.call(t),x=y[f];",k=0;7>k;k++)e+="n='"+r.h[k]+"';if((!(r&&x[n])&&m.call(t,n))",r.j||(e+="||(!x[n]&&t[n]!==A[n])"),e+="){"+r.g+"}";
e+="}"}return(r.b||_t.nonEnumArgs)&&(e+="}"),e+=r.c+";return E",n("d,j,k,m,o,p,q,s,v,A,B,y,I,J,L",t+e+"}")(a,J,ot,st,B,b,Et,O,U.f,ut,X,Ot,H,ft,at)}function y(){var t=(t=o.indexOf)===A?n:t;return t}function v(n){return typeof n=="function"&&it.test(n)}function h(n){var r,e;return!n||at.call(n)!=V||(r=n.constructor,d(r)&&!(r instanceof r))||!_t.argsClass&&b(n)||!_t.nodeClass&&t(n)?false:_t.ownLast?(Ct(n,function(n,t,r){return e=st.call(r,t),false}),false!==e):(Ct(n,function(n,t){e=t}),typeof e=="undefined"||st.call(n,e))
}function b(n){return n&&typeof n=="object"&&typeof n.length=="number"&&at.call(n)==$||false}function m(n){var t=[];return Ct(n,function(n,r){d(n)&&t.push(r)}),t.sort()}function d(n){return typeof n=="function"}function j(n){return!(!n||!X[typeof n])}function O(n){return typeof n=="string"||n&&typeof n=="object"&&at.call(n)==H||false}function _(n,t,r){var e=-1,o=y(),u=n?n.length:0,f=false;return r=(0>r?dt(0,u+r):r)||0,Et(n)?f=-1<o(n,t,r):typeof u=="number"?f=-1<(O(n)?n.indexOf(t,r):o(n,t,r)):kt(n,function(n){return++e<r?void 0:!(f=n===t)
}),f}function w(n,t,r){if(t&&typeof r=="undefined"&&Et(n)){r=-1;for(var e=n.length;++r<e&&false!==t(n[r],r,n););}else kt(n,t,r);return n}function E(n,t,r){var e=-1,u=n?n.length:0,f=Array(typeof u=="number"?u:0);if(t=o.createCallback(t,r,3),Et(n))for(;++e<u;)f[e]=t(n[e],e,n);else kt(n,function(n,r,o){f[++e]=t(n,r,o)});return f}function x(n,t,r){var u=0,f=n?n.length:0;if(typeof t!="number"&&null!=t){var a=-1;for(t=o.createCallback(t,r,3);++a<f&&t(n[a],a,n);)u++}else if(u=t,null==u||r)return n?n[0]:I;return e(n,0,jt(dt(0,u),f))
}function A(t,r,e){if(typeof e=="number"){var o=t?t.length:0;e=0>e?dt(0,o+e):e||0}else if(e)return e=C(t,r),t[e]===r?e:-1;return n(t,r,e)}function C(n,t,r,e){var u=0,f=n?n.length:u;for(r=r?o.createCallback(r,e,1):P,t=r(t);u<f;)e=u+f>>>1,r(n[e])<t?u=e+1:f=e;return u}function S(n,t){return 2<arguments.length?p(n,17,e(arguments,2),null,t):p(n,1,null,null,t)}function P(n){return n}function D(){}function F(n){return function(t){return t[n]}}var I,L=[],B={},N=40,R=/^\s*function[ \n\r\t]+\w/,T=/\bthis\b/,K="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),$="[object Arguments]",q="[object Array]",z="[object Boolean]",G="[object Date]",J="[object Error]",M="[object Number]",V="[object Object]",W="[object RegExp]",H="[object String]",Q={configurable:false,enumerable:false,value:null,writable:false},U={a:"",b:null,c:"",d:"",e:"",v:null,g:"",h:null,support:null,i:"",j:false},X={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},Y=X[typeof window]&&window||this,Z=X[typeof exports]&&exports&&!exports.nodeType&&exports,nt=X[typeof module]&&module&&!module.nodeType&&module,tt=nt&&nt.exports===Z&&Z,rt=X[typeof global]&&global;
!rt||rt.global!==rt&&rt.window!==rt||(Y=rt);var et=[],ot=Error.prototype,ut=Object.prototype,ft=String.prototype,at=ut.toString,it=RegExp("^"+(at+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),ct=Function.prototype.toString,lt=v(lt=Object.getPrototypeOf)&&lt,st=ut.hasOwnProperty,pt=et.push,gt=ut.propertyIsEnumerable,yt=et.unshift,vt=function(){try{var n={},t=v(t=Object.defineProperty)&&t,r=t(n,n,n)&&t}catch(e){}return r}(),ht=v(ht=Object.create)&&ht,bt=v(bt=Array.isArray)&&bt,mt=v(mt=Object.keys)&&mt,dt=Math.max,jt=Math.min,Ot={};
Ot[q]=Ot[G]=Ot[M]={constructor:true,toLocaleString:true,toString:true,valueOf:true},Ot[z]=Ot[H]={constructor:true,toString:true,valueOf:true},Ot[J]=Ot["[object Function]"]=Ot[W]={constructor:true,toString:true},Ot[V]={constructor:true},function(){for(var n=K.length;n--;){var t,r=K[n];for(t in Ot)st.call(Ot,t)&&!st.call(Ot[t],r)&&(Ot[t][r]=false)}}();var _t=o.support={};!function(){function n(){this.x=1}var t={0:1,length:1},r=[];n.prototype={valueOf:1,y:1};for(var e in new n)r.push(e);for(e in arguments);_t.argsClass=at.call(arguments)==$,_t.argsObject=arguments.constructor==Object&&!(arguments instanceof Array),_t.enumErrorProps=gt.call(ot,"message")||gt.call(ot,"name"),_t.enumPrototypes=gt.call(n,"prototype"),_t.funcDecomp=!v(Y.k)&&T.test(function(){return this
}),_t.funcNames=typeof Function.name=="string",_t.nonEnumArgs=0!=e,_t.nonEnumShadows=!/valueOf/.test(r),_t.ownLast="x"!=r[0],_t.spliceObjects=(et.splice.call(t,0,1),!t[0]),_t.unindexedChars="xx"!="x"[0]+Object("x")[0];try{_t.nodeClass=!(at.call(document)==V&&!({toString:0}+""))}catch(o){_t.nodeClass=true}}(1),ht||(f=function(){function n(){}return function(t){if(j(t)){n.prototype=t;var r=new n;n.prototype=null}return r||Y.Object()}}());var wt=vt?function(n,t){Q.value=t,vt(n,"__bindData__",Q)}:D;_t.argsClass||(b=function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&st.call(n,"callee")&&!gt.call(n,"callee")||false
});var Et=bt||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&at.call(n)==q||false},xt=g({a:"z",e:"[]",i:"if(!(B[typeof z]))return E",g:"E.push(n)"}),At=mt?function(n){return j(n)?_t.enumPrototypes&&typeof n=="function"||_t.nonEnumArgs&&n.length&&b(n)?xt(n):mt(n):[]}:xt,rt={a:"g,e,K",i:"e=e&&typeof K=='undefined'?e:d(e,K,3)",b:"typeof u=='number'",v:At,g:"if(e(t[n],n,g)===false)return E"},bt={i:"if(!B[typeof t])return E;"+rt.i,b:false},kt=g(rt),Ct=g(rt,bt,{j:false}),St=g(rt,bt);d(/x/)&&(d=function(n){return typeof n=="function"&&"[object Function]"==at.call(n)
});var Pt=lt?function(n){if(!n||at.call(n)!=V||!_t.argsClass&&b(n))return false;var t=n.valueOf,r=v(t)&&(r=lt(t))&&lt(r);return r?n==r||lt(n)==r:h(n)}:h;o.bind=S,o.bindAll=function(n){for(var t=1<arguments.length?c(arguments,true,false,1):m(n),r=-1,e=t.length;++r<e;){var o=t[r];n[o]=p(n[o],1,null,null,n)}return n},o.createCallback=function(n,t,r){var e=typeof n;if(null==n||"function"==e)return a(n,t,r);if("object"!=e)return F(n);var o=At(n),u=o[0],f=n[u];return 1!=o.length||f!==f||j(f)?function(t){for(var r=o.length,e=false;r--&&(e=l(t[o[r]],n[o[r]],null,true)););return e
}:function(n){return n=n[u],f===n&&(0!==f||1/f==1/n)}},o.forEach=w,o.forIn=Ct,o.forOwn=St,o.functions=m,o.invoke=function(n,t){var r=e(arguments,2),o=-1,u=typeof t=="function",f=n?n.length:0,a=Array(typeof f=="number"?f:0);return w(n,function(n){a[++o]=(u?t:n[t]).apply(n,r)}),a},o.keys=At,o.map=E,o.merge=function(n){var t=arguments,o=2;if(!j(n))return n;if("number"!=typeof t[2]&&(o=t.length),3<o&&"function"==typeof t[o-2])var u=a(t[--o-1],t[o--],2);else 2<o&&"function"==typeof t[o-1]&&(u=t[--o]);
for(var t=e(arguments,1,o),f=-1,i=L.pop()||[],c=L.pop()||[];++f<o;)s(n,t[f],u,i,c);return r(i),r(c),n},o.property=F,o.values=function(n){for(var t=-1,r=At(n),e=r.length,o=Array(e);++t<e;)o[t]=n[r[t]];return o},o.collect=E,o.each=w,o.methods=m,o.contains=_,o.identity=P,o.indexOf=A,o.isArguments=b,o.isArray=Et,o.isEqual=function(n,t,r,e){return l(n,t,typeof r=="function"&&a(r,e,2))},o.isFunction=d,o.isObject=j,o.isPlainObject=Pt,o.isString=O,o.noop=D,o.result=function(n,t){if(n){var r=n[t];return d(r)?n[t]():r
}},o.sortedIndex=C,o.include=_,o.first=x,o.take=x,o.head=x,o.VERSION="2.4.1",Z&&nt&&tt&&((nt.exports=o)._=o)}).call(this);

View File

@ -13,12 +13,12 @@ var levels = ["debug", "info", "warn", "error", "fatal"];
var BasicLogger = require("./logger/basic_logger"),
NullLogger = require("./logger/null_logger"),
Config = require("./config"),
_ = require("./lodash");
_ = require("./utils/helpers");
var Logger = module.exports = {
setup: function(opts) {
if (typeof opts === "object") {
_.merge(Config.logging, opts);
if (_.isObject(opts)) {
Config.logging = _.extend(Config.logging, opts);
}
var logger = Config.logging.logger,
@ -39,7 +39,7 @@ var Logger = module.exports = {
Logger.setup();
_.each(levels, function(level) {
levels.forEach(function(level) {
Logger[level] = function() {
if (levels.indexOf(level) >= levels.indexOf(Logger.level)) {
return Logger.logger[level].apply(Logger.logger, arguments);

View File

@ -12,7 +12,7 @@ var initializer = require("./initializer"),
Logger = require("./logger"),
Utils = require("./utils"),
Config = require("./config"),
_ = require("./lodash");
_ = require("./utils/helpers");
var Async = require("async"),
EventEmitter = require("events").EventEmitter;
@ -41,13 +41,15 @@ var Robot = module.exports = function Robot(opts) {
"log"
];
_.bindAll(this, methods);
methods.forEach(function(method) {
this[method] = this[method].bind(this);
}, this);
this.initRobot(opts);
this.initConnections(opts);
this.initDevices(opts);
_.forEach(opts, function(opt, name) {
_.each(opts, function(opt, name) {
if (this[name] !== undefined) {
return;
}
@ -60,9 +62,15 @@ var Robot = module.exports = function Robot(opts) {
}, this);
if (opts.commands) {
var cmds = _.result(opts, "commands");
var cmds;
if (_.isObject(cmds) && !_.isArray(cmds)) {
if (_.isFunction(opts.commands)) {
cmds = opts.commands.call(this);
} else {
cmds = opts.commands;
}
if (_.isObject(cmds)) {
this.commands = cmds;
} else {
var err = "#commands must be an object ";
@ -96,7 +104,7 @@ Robot.prototype.toJSON = function() {
name: this.name,
connections: _.invoke(this.connections, "toJSON"),
devices: _.invoke(this.devices, "toJSON"),
commands: _.keys(this.commands),
commands: Object.keys(this.commands),
events: _.isArray(this.events) ? this.events : []
};
};
@ -159,22 +167,21 @@ Robot.prototype.initConnections = function(opts) {
return this.connections;
}
if (_.isObject(opts.connections)) {
if (_.isObjectLoose(opts.connections)) {
if (_.isArray(opts.connections)) {
this.performArraySetup(opts.connections, "connection", "connections");
return this.connections;
}
_.forIn(opts.connections, function(conn, key) {
_.each(opts.connections, function(conn, key) {
var name = _.isString(key) ? key : conn.name;
if (conn.devices) {
_.forIn(conn.devices, function(device, deviceName) {
opts.devices = opts.devices || {};
opts.devices = opts.devices || {};
_.each(conn.devices, function(device, d) {
device.connection = name;
opts.devices[deviceName] = device;
opts.devices[d] = device;
});
delete conn.devices;
@ -202,7 +209,7 @@ Robot.prototype.device = function(name, device) {
this.log("warn", str);
}
if (typeof device.connection === "string") {
if (_.isString(device.connection)) {
if (this.connections[device.connection] == null) {
str = "No connection found with the name " + device.connection + ".\n";
this.log("fatal", str);
@ -211,7 +218,10 @@ Robot.prototype.device = function(name, device) {
device.connection = this.connections[device.connection];
} else {
device.connection = _.first(_.values(this.connections));
for (var c in this.connections) {
device.connection = this.connections[c];
break;
}
}
this.devices[device.name] = initializer("driver", device);
@ -242,13 +252,13 @@ Robot.prototype.initDevices = function(opts) {
return this.devices;
}
if (_.isObject(opts.devices)) {
if (_.isObjectLoose(opts.devices)) {
if (_.isArray(opts.devices)) {
this.performArraySetup(opts.devices, "device", "devices");
return this.devices;
}
_.forIn(opts.devices, function(device, key) {
_.each(opts.devices, function(device, key) {
var name = _.isString(key) ? key : device.name;
this.device(name, device);
}, this);
@ -285,7 +295,7 @@ Robot.prototype.start = function(callback) {
this.log("fatal", err);
this.halt(function() {
if (typeof(this.error) === "function") {
if (_.isFunction(this.error)) {
this.error.call(this, err);
}
@ -386,8 +396,8 @@ Robot.prototype.halt = function(callback) {
return callback();
}
var devices = _.map(this.devices, "halt");
var connections = _.map(this.connections, "disconnect");
var devices = _.pluck(this.devices, "halt"),
connections = _.pluck(this.connections, "disconnect");
try {
Async.parallel(devices, function() {
@ -423,8 +433,8 @@ Robot.prototype.performArraySetup = function(things, typeOfThing, arrayName) {
this.log("warn", str);
_.forEach(things, function(t, key) {
var name = _.isString(key) ? key : t.name;
things.forEach(function(t, key) {
var name = _.isString(key) === "string" ? key : t.name;
this[typeOfThing](name, t);
}, this);
};

View File

@ -8,8 +8,9 @@
"use strict";
var _ = require("./lodash"),
monkeyPatches = require("./utils/monkey-patches");
var _ = require("./utils/helpers");
var monkeyPatches = require("./utils/monkey-patches");
var Utils = module.exports = {
// Public: Alias to setInterval, combined with Number monkeypatches below to
@ -94,9 +95,11 @@ var Utils = module.exports = {
this.constructor = child;
};
_.forOwn(parent, function(prop, key) {
child[key] = prop;
});
for (var key in parent) {
if (parent.hasOwnProperty(key)) {
child[key] = parent[key];
}
}
Ctor.prototype = parent.prototype;
child.prototype = new Ctor();
@ -105,7 +108,7 @@ var Utils = module.exports = {
},
proxyFunctions: function proxyFunctions(source, target) {
_.forEach(source, function(prop, key) {
_.each(source, function(prop, key) {
if (_.isFunction(prop) && !target[key]) {
target[key] = prop.bind(source);
}
@ -129,7 +132,7 @@ var Utils = module.exports = {
force = force || false;
_.forEach(methods, function(method) {
methods.forEach(function(method) {
if (_.isFunction(base[method]) && !force) {
return;
}
@ -184,7 +187,7 @@ var Utils = module.exports = {
throw new Error("key not found: \"" + property + "\"");
}
if (typeof(fallback) === "function") {
if (_.isFunction(fallback)) {
var value = fallback(property);
if (value === void 0) {

204
lib/utils/helpers.js Normal file
View File

@ -0,0 +1,204 @@
// A collection of useful helper functions, used internally but not exported
// with the rest of Cylon.
"use strict";
var __slice = Array.prototype.slice;
var H = module.exports = {};
function identity(value) {
return value;
}
function extend(base, source) {
var isArray = Array.isArray(source);
if (base == null) {
base = isArray ? [] : {};
}
if (isArray) {
source.forEach(function(e, i) {
if (typeof base[i] === "undefined") {
base[i] = e;
} else if (typeof e === "object") {
base[i] = extend(base[i], e);
} else {
if (!~base.indexOf(e)) {
base.push(e);
}
}
});
} else {
var key;
for (key in source) {
if (typeof source[key] !== "object" || !source[key]) {
base[key] = source[key];
} else {
if (base[key]) {
extend(base[key], source[key]);
} else {
base[key] = source[key];
}
}
}
}
return base;
}
extend(H, {
identity: identity,
extend: extend
});
function kind(thing) {
return Object.prototype.toString.call(thing).slice(8, -1);
}
function isA(type) {
return function(thing) {
return kind(thing) === type;
};
}
extend(H, {
isObject: isA("Object"),
isObjectLoose: function(thing) { return typeof thing === "object"; },
isFunction: isA("Function"),
isArray: isA("Array"),
isString: isA("String"),
isNumber: isA("Number"),
isArguments: isA("Arguments"),
isUndefined: isA("Undefined")
});
function iterate(thing, fn, thisVal) {
if (H.isArray(thing)) {
thing.forEach(fn, thisVal);
return;
}
if (H.isObject(thing)) {
for (var key in thing) {
var value = thing[key];
fn.call(thisVal, value, key);
}
}
return [];
}
function pluck(collection, key) {
var keys = [];
iterate(collection, function(object) {
if (H.isObject(object)) {
if (H.isFunction(object[key])) {
keys.push(object[key].bind(object));
} else {
keys.push(object[key]);
}
}
});
return keys;
}
function map(collection, fn, thisVal) {
var vals = [];
if (fn == null) {
fn = identity;
}
iterate(collection, function(object, index) {
vals.push(fn.call(thisVal, object, index));
});
return vals;
}
function invoke(collection, fn) {
var args = __slice.call(arguments, 2),
vals = [];
iterate(collection, function(object) {
if (H.isFunction(fn)) {
vals.push(fn.apply(object, args));
return;
}
vals.push(object[fn].apply(object, arguments));
});
return vals;
}
function reduce(collection, iteratee, accumulator, thisVal) {
var isArray = H.isArray(collection);
if (!isArray && !H.isObjectLoose(collection)) {
return null;
}
if (iteratee == null) {
iteratee = identity;
}
if (accumulator == null) {
if (isArray) {
accumulator = collection.shift();
} else {
for (var key in collection) {
accumulator = collection[key];
delete collection[key];
break;
}
}
}
iterate(collection, function(object, key) {
accumulator = iteratee.call(thisVal, accumulator, object, key);
});
return accumulator;
}
extend(H, {
pluck: pluck,
each: iterate,
map: map,
invoke: invoke,
reduce: reduce
});
function arity(fn, n) {
return function() {
var args = __slice.call(arguments, 0, n);
return fn.apply(null, args);
};
}
function partial(fn) {
var args = __slice.call(arguments, 1);
return function() {
return fn.apply(null, args.concat(__slice.call(arguments)));
};
}
function partialRight(fn) {
var args = __slice.call(arguments, 1);
return function() {
return fn.apply(null, __slice.call(arguments).concat(args));
};
}
extend(H, {
arity: arity,
partial: partial,
partialRight: partialRight
});

View File

@ -0,0 +1,280 @@
"use strict";
var _ = source("utils/helpers");
describe("Helpers", function() {
describe("extend", function() {
var extend = _.extend;
var base = {
fruits: ["apple"],
vegetables: ["beet"],
thing: null,
otherThing: "hello!",
data: [{ "user": "barney" }, { "user": "fred" }]
};
var source = {
fruits: ["banana"],
vegetables: ["carrot"],
thing: "hello!",
otherThing: null,
data: [{ "age": 36 }, { "age": 40 }]
};
var expected = {
data: [ { age: 36, user: "barney" }, { age: 40, user: "fred" } ],
fruits: [ "apple", "banana" ],
vegetables: [ "beet", "carrot" ],
thing: "hello!",
otherThing: null
};
it("extends two objects", function() {
var extended = extend(base, source);
expect(extended).to.be.eql(expected);
});
});
describe("isObject", function() {
var fn =_.isObject;
it("checks if a value is an Object", function() {
var Klass = function() {},
instance = new Klass();
expect(fn({})).to.be.eql(true);
expect(fn(instance)).to.be.eql(true);
expect(fn([])).to.be.eql(false);
expect(fn(function() {})).to.be.eql(false);
expect(fn(10)).to.be.eql(false);
expect(fn("")).to.be.eql(false);
});
});
describe("isFunction", function() {
var fn =_.isFunction;
it("checks if a value is a Function", function() {
expect(fn(function() {})).to.be.eql(true);
expect(fn({})).to.be.eql(false);
expect(fn([])).to.be.eql(false);
expect(fn(10)).to.be.eql(false);
expect(fn("")).to.be.eql(false);
});
});
describe("isArray", function() {
var fn = _.isArray;
it("checks if a value is an Array", function() {
expect(fn([])).to.be.eql(true);
expect(fn(function() {})).to.be.eql(false);
expect(fn({})).to.be.eql(false);
expect(fn(10)).to.be.eql(false);
expect(fn("")).to.be.eql(false);
});
});
describe("isNumber", function() {
var fn = _.isNumber;
it("checks if a value is a Number", function() {
expect(fn(10)).to.be.eql(true);
expect(fn(function() {})).to.be.eql(false);
expect(fn({})).to.be.eql(false);
expect(fn([])).to.be.eql(false);
expect(fn("")).to.be.eql(false);
});
});
describe("isString", function() {
var fn = _.isString;
it("checks if a value is a String", function() {
expect(fn("")).to.be.eql(true);
expect(fn(10)).to.be.eql(false);
expect(fn(function() {})).to.be.eql(false);
expect(fn({})).to.be.eql(false);
expect(fn([])).to.be.eql(false);
});
});
describe("#pluck", function() {
var object = { a: { item: "hello" }, b: { item: "world" } },
array = [ { item: "hello" }, { item: "world" } ];
it("plucks values from a collection", function() {
expect(_.pluck(object, "item")).to.be.eql(["hello", "world"]);
expect(_.pluck(array, "item")).to.be.eql(["hello", "world"]);
});
});
describe("#map", function() {
var object = { a: { item: "hello" }, b: { item: "world" } },
array = [ { item: "hello" }, { item: "world" } ];
var fn = function(value, key) {
return [value, key];
};
it("runs a function over items in a collection", function() {
expect(_.map(object, fn)).to.be.eql([
[{ item: "hello" }, "a"],
[{ item: "world" }, "b"]
]);
expect(_.map(array, fn)).to.be.eql([
[{ item: "hello" }, 0],
[{ item: "world" }, 1]
]);
});
it("defaults to the identity function", function() {
expect(_.map(array)).to.be.eql(array);
expect(_.map(object)).to.be.eql(array);
});
});
describe("#invoke", function() {
var array = [
{
name: "bob",
toString: function() {
return "Hi from " + this.name;
}
},
{
name: "dave",
toString: function() {
return "hello from " + this.name;
}
}
];
var object = {
bob: {
name: "bob",
toString: function() {
return "Hi from " + this.name;
}
},
dave: {
name: "dave",
toString: function() {
return "hello from " + this.name;
}
}
};
it("runs a instance function over items in a collection", function() {
expect(_.invoke(object, "toString")).to.be.eql([
"Hi from bob",
"hello from dave"
]);
expect(_.invoke(array, "toString")).to.be.eql([
"Hi from bob",
"hello from dave"
]);
expect(_.invoke([1, 2, 3, 4, 5], Number.prototype.toString)).to.be.eql([
"1", "2", "3", "4", "5"
]);
});
});
describe("#each", function() {
var object = { a: { item: "hello" }, b: { item: "world" } },
array = [ { item: "hello" }, { item: "world" } ];
var fn = function(value, key) {
return [value, key];
};
it("runs a function over items in a collection", function() {
fn = spy();
_.map(object, fn);
expect(fn).to.be.calledWith(object.a, "a");
expect(fn).to.be.calledWith(object.b, "b");
fn = spy();
_.map(array, fn);
expect(fn).to.be.calledWith(array[0], 0);
expect(fn).to.be.calledWith(array[1], 1);
});
});
describe("#reduce", function() {
var arr = [1, 2, 3, 4, 5, 6],
obj = { a: 1, b: 2 };
function add(sum, n) { return sum + n; }
it("reduces over a collection with the provided iteratee", function() {
expect(_.reduce(arr, add, 0)).to.be.eql(21);
expect(_.reduce(obj, add, 0)).to.be.eql(3);
});
it("defaults to the first value for the accumulator", function() {
var obj = {
a: { name: "hello" },
b: { name: "world" }
};
expect(_.reduce(arr, add)).to.be.eql(21);
expect(
_.reduce(obj, function(acc, val) {
acc.name += " " + val.name;
return acc;
})
).to.be.eql({ name: "hello world"});
});
it("supports providing a `this` value", function() {
var self = {
toString: function(y) { return y.toString(); }
};
var fn = function(acc, val) {
return acc + this.toString(val);
};
expect(_.reduce(arr, fn, 1, self)).to.be.eql("123456");
});
});
describe("#arity", function() {
it("creates a function that only takes a certain # of args", function() {
var fn = spy();
var one = _.arity(fn, 1);
one("one", "two", "three");
expect(fn).to.be.calledWith("one");
});
});
describe("#partial", function() {
it("partially applies a function's arguments", function() {
var fn = spy();
var one = _.partial(fn, "one", "two");
one("three");
expect(fn).to.be.calledWith("one", "two", "three");
});
});
describe("#partialRight", function() {
it("partially applies arguments to the end of a fn call", function() {
var fn = spy();
var one = _.partialRight(fn, "two", "three");
one("one");
expect(fn).to.be.calledWith("one", "two", "three");
});
});
});