From 3c6696a78fe9a17f9dc9b53558d65ccd627bbaae Mon Sep 17 00:00:00 2001 From: Andrew Stewart Date: Mon, 10 Mar 2014 12:00:48 -0700 Subject: [PATCH] Reorganize Utils for easier testing --- lib/utils.js | 311 ++++++++++++++++++++++++++------------------------- 1 file changed, 159 insertions(+), 152 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index b83afc7..f285374 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -6,158 +6,6 @@ * Licensed under the Apache 2.0 license. */ -// Public: Alias to setInterval, combined with Number monkeypatches below to -// create an artoo-like syntax. -// -// interval - interval to run action on -// action - action to perform at interval -// -// Examples -// -// every 5.seconds(), -> console.log("hello world (and again in 5 seconds)!") -// -// Returns an interval -global.every = function(interval, action) { - return setInterval(action, interval); -}; - -// Public: Alias to setTimeout, combined with Number monkeypatches below to -// create an artoo-like syntax. -// -// interval - interval to run action on -// action - action to perform at interval -// -// Examples -// -// after 10.seconds(), -> console.log("hello world from ten seconds ago!") -// -// Returns an interval -global.after = function(delay, action) { - return setTimeout(action, delay); -}; - -// Public: Alias to the `every` function, but passing 0 -// Examples -// -// constantly -> console.log("hello world (and again and again)!") -// -// Returns an interval -global.constantly = function(action) { - return every(0, action); -}; - -// Public: Sleep - do nothing for some duration of time. -// -// ms - number of ms to sleep for -// -// Returns a function -// Examples: -// sleep 1.second() -global.sleep = function(ms) { - var start = Date.now(); - - while(Date.now() < start + ms) { - var i = 0; - } -}; - -// Copies -global.slice = [].slice; -global.hasProp = {}.hasOwnProperty; - -// Public: Function to use for class inheritance. Copy of a CoffeeScript helper -// function. -// -// Example -// -// var Sphero = (function(klass) { -// subclass(Sphero, klass); -// // Sphero is now a subclass of Parent, and can access it's methods through -// // Sphero.__super__ -// })(Parent); -// -// Returns subclass -global.subclass = function(child, parent) { - var ctor = function() { this.constructor = child; }; - - for (var key in parent) { - if (hasProp.call(parent, key)) { child[key] = parent[key]; } - } - - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - child.__super__ = parent.prototype; - return child; -}; - -// Public: Proxies a list of methods from one object to another. It will not -// overwrite existing methods unless told to. -// -// methods - array of functions to proxy -// target - object to proxy the functions to -// base - (optional) object that proxied functions will be declared on. Defaults -// to this -// force - (optional) boolean - whether or not to force method assignment -// -// Returns base -global.proxyFunctionsToObject = function(methods, target, base, force) { - if (base == null) { base = this; } - if (force == null) { force = false; } - - var fn = function(method) { - return base[method] = function() { - var args = arguments.length >= 1 ? [].slice.call(arguments, 0) : []; - return target[method].apply(target, args); - }; - }; - - for (var i = 0; i < methods.length; i++) { - var method = methods[i]; - if (!force) { - if (typeof base[method] === 'function') { continue; } - } - - fn(method); - } - return base; -}; - -// Public: Proxies a list of methods for test stubbing. -// -// methods - array of functions to proxy -// base - (optional) object that proxied functions will be declared on. Defaults -// to this -// -// Returns base -global.proxyTestStubs = function(methods, base) { - if (base == null) { base = this; } - - methods.forEach(function(method) { - base[method] = function() { return true; }; - base.commandList.push(method); - }); - - return base; -}; - -// Public: Binds an argument to a caller -// -// fn - function to bind -// me - value for 'this' scope inside the function -// -// Examples -// -// var me = { hello: "Hello World" }; -// var proxy = { boundMethod: function() { return this.hello; } }; -// proxy.boundMethod = bind(proxy.boundMethod, me); -// proxy.boundMethod(); -// //=> "Hello World" -// -// Returns a function wrapper -global.bind = function(fn, me) { - return function() { return fn.apply(me, arguments); }; -}; - // Public: Monkey-patches Number to have Rails-like //seconds() function. Warning, // due to the way the Javascript parser works, applying functions on numbers is // kind of weird. See examples for details. @@ -219,3 +67,162 @@ Number.prototype.fromScale = function(start, end) { Number.prototype.toScale = function(start, end) { return Math.ceil(this * (Math.max(start, end) - Math.min(start, end)) + Math.min(start, end)); }; + +var Utils = { + // Public: Alias to setInterval, combined with Number monkeypatches below to + // create an artoo-like syntax. + // + // interval - interval to run action on + // action - action to perform at interval + // + // Examples + // + // every 5.seconds(), -> console.log("hello world (and again in 5 seconds)!") + // + // Returns an interval + every: function(interval, action) { + return setInterval(action, interval); + }, + + // Public: Alias to setTimeout, combined with Number monkeypatches below to + // create an artoo-like syntax. + // + // interval - interval to run action on + // action - action to perform at interval + // + // Examples + // + // after 10.seconds(), -> console.log("hello world from ten seconds ago!") + // + // Returns an interval + after: function(delay, action) { + return setTimeout(action, delay); + }, + + // Public: Alias to the `every` function, but passing 0 + // Examples + // + // constantly -> console.log("hello world (and again and again)!") + // + // Returns an interval + constantly: function(action) { + return every(0, action); + }, + + // Public: Sleep - do nothing for some duration of time. + // + // ms - number of ms to sleep for + // + // Returns a function + // Examples: + // sleep 1.second() + sleep: function(ms) { + var start = Date.now(); + + while(Date.now() < start + ms) { + var i = 0; + } + }, + + // Copies + slice: [].slice, + hasProp: {}.hasOwnProperty, + + // Public: Function to use for class inheritance. Copy of a CoffeeScript helper + // function. + // + // Example + // + // var Sphero = (function(klass) { + // subclass(Sphero, klass); + // // Sphero is now a subclass of Parent, and can access it's methods through + // // Sphero.__super__ + // })(Parent); + // + // Returns subclass + subclass: function(child, parent) { + var ctor = function() { this.constructor = child; }; + + for (var key in parent) { + if (hasProp.call(parent, key)) { child[key] = parent[key]; } + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; + }, + + // Public: Proxies a list of methods from one object to another. It will not + // overwrite existing methods unless told to. + // + // methods - array of functions to proxy + // target - object to proxy the functions to + // base - (optional) object that proxied functions will be declared on. Defaults + // to this + // force - (optional) boolean - whether or not to force method assignment + // + // Returns base + proxyFunctionsToObject: function(methods, target, base, force) { + if (base == null) { base = this; } + if (force == null) { force = false; } + + var fn = function(method) { + return base[method] = function() { + var args = arguments.length >= 1 ? [].slice.call(arguments, 0) : []; + return target[method].apply(target, args); + }; + }; + + for (var i = 0; i < methods.length; i++) { + var method = methods[i]; + if (!force) { + if (typeof base[method] === 'function') { continue; } + } + + fn(method); + } + return base; + }, + + // Public: Proxies a list of methods for test stubbing. + // + // methods - array of functions to proxy + // base - (optional) object that proxied functions will be declared on. Defaults + // to this + // + // Returns base + proxyTestStubs: function(methods, base) { + if (base == null) { base = this; } + + methods.forEach(function(method) { + base[method] = function() { return true; }; + base.commandList.push(method); + }); + + return base; + }, + + // Public: Binds an argument to a caller + // + // fn - function to bind + // me - value for 'this' scope inside the function + // + // Examples + // + // var me = { hello: "Hello World" }; + // var proxy = { boundMethod: function() { return this.hello; } }; + // proxy.boundMethod = bind(proxy.boundMethod, me); + // proxy.boundMethod(); + // //=> "Hello World" + // + // Returns a function wrapper + bind: function(fn, me) { + return function() { return fn.apply(me, arguments); }; + } +}; + +// Add all utility functions to global namespace +for (var util in Utils) { global[util] = Utils[util]; } + +module.exports = Utils;