Skip to content
Browse files

[CB-634] need an sprintf implementation in utils

* added utils.format() to utils.js
* added test cases for utils.format() in test.utils.js
* added some additional safety checks in the packager
  for the debug bundles
* drive-by adding --verbose to .wr file

Note that I also "refactored the source" of the
utils.js module, which I'll be discussing on the
m/l.
  • Loading branch information...
1 parent 9cfdc13 commit 2da5b44e4a603cf699279d7ef6b8d5d1b07b17ad @pmuellr pmuellr committed May 4, 2012
Showing with 237 additions and 83 deletions.
  1. +1 −0 .wr
  2. +7 −0 build/packager.js
  3. +154 −83 lib/common/utils.js
  4. +75 −0 test/test.utils.js
View
1 .wr
@@ -25,6 +25,7 @@
--stdoutcolor blue
--stderrcolor red
+--verbose
jake
View
7 build/packager.js
@@ -166,6 +166,13 @@ function writeContents(oFile, fileName, contents, debug) {
contents += '\n//@ sourceURL=' + fileName
contents = 'eval(' + JSON.stringify(contents) + ')'
+
+ // this bit makes it easier to identify modules
+ // with syntax errors in them
+ var handler = 'console.log("exception: in ' + fileName + ': " + e);'
+ handler += 'console.log(e.stack);'
+
+ contents = 'try {' + contents + '} catch(e) {' + handler + '}'
}
else {
View
237 lib/common/utils.js
@@ -1,3 +1,147 @@
+var utils = exports
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+ return Object.prototype.toString.call(a) == '[object Array]';
+}
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+ return Object.prototype.toString.call(d) == '[object Date]';
+}
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+ if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+ return obj;
+ }
+
+ var retVal, i;
+
+ if(utils.isArray(obj)){
+ retVal = [];
+ for(i = 0; i < obj.length; ++i){
+ retVal.push(utils.clone(obj[i]));
+ }
+ return retVal;
+ }
+
+ retVal = {};
+ for(i in obj){
+ if(!(i in retVal) || retVal[i] != obj[i]) {
+ retVal[i] = utils.clone(obj[i]);
+ }
+ }
+ return retVal;
+}
+
+/**
+ * Returns a wrappered version of the function
+ */
+utils.close = function(context, func, params) {
+ if (typeof params == 'undefined') {
+ return function() {
+ return func.apply(context, arguments);
+ };
+ } else {
+ return function() {
+ return func.apply(context, params);
+ };
+ }
+}
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+ return UUIDcreatePart(4) + '-' +
+ UUIDcreatePart(2) + '-' +
+ UUIDcreatePart(2) + '-' +
+ UUIDcreatePart(2) + '-' +
+ UUIDcreatePart(6);
+}
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = function() {
+ // proxy used to establish prototype chain
+ var F = function() {};
+ // extend Child from Parent
+ return function(Child, Parent) {
+ F.prototype = Parent.prototype;
+ Child.prototype = new F();
+ Child.__super__ = Parent.prototype;
+ Child.prototype.constructor = Child;
+ };
+}
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+ if (alert) {
+ alert(msg);
+ } else if (console && console.log) {
+ console.log(msg);
+ }
+}
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * format chars:
+ * %j - format arg as JSON
+ * %o - format arg as JSON
+ * %c - format arg as ''
+ * %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ * http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.format = function(formatString /* ,... */) {
+ if (formatString == null) return ""
+ if (arguments.length == 1) return formatString.toString()
+
+ var pattern = /(.*?)%(.)(.*)/
+ var rest = formatString.toString()
+ var result = []
+ var args = [].slice.call(arguments,1)
+
+ while (args.length) {
+ var arg = args.shift()
+ var match = pattern.exec(rest)
+
+ if (!match) break
+
+ rest = match[3]
+
+ result.push(match[1])
+
+ if (match[2] == '%') {
+ result.push('%')
+ args.unshift(arg)
+ continue
+ }
+
+ result.push(formatted(arg, match[2]))
+ }
+
+ result.push(rest)
+
+ return result.join('')
+}
+
+//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
var uuidpart = "";
for (var i=0; i<length; i++) {
@@ -10,89 +154,16 @@ function UUIDcreatePart(length) {
return uuidpart;
}
-var _self = {
- isArray:function(a) {
- return Object.prototype.toString.call(a) == '[object Array]';
- },
- isDate:function(d) {
- return Object.prototype.toString.call(d) == '[object Date]';
- },
- /**
- * Does a deep clone of the object.
- */
- clone: function(obj) {
- if(!obj || typeof obj == 'function' || _self.isDate(obj) || typeof obj != 'object') {
- return obj;
- }
-
- var retVal, i;
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
- if(_self.isArray(obj)){
- retVal = [];
- for(i = 0; i < obj.length; ++i){
- retVal.push(_self.clone(obj[i]));
- }
- return retVal;
- }
-
- retVal = {};
- for(i in obj){
- if(!(i in retVal) || retVal[i] != obj[i]) {
- retVal[i] = _self.clone(obj[i]);
- }
- }
- return retVal;
- },
-
- close: function(context, func, params) {
- if (typeof params == 'undefined') {
- return function() {
- return func.apply(context, arguments);
- };
- } else {
- return function() {
- return func.apply(context, params);
- };
- }
- },
-
- /**
- * Create a UUID
- */
- createUUID: function() {
- return UUIDcreatePart(4) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(6);
- },
-
- /**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
- extend: (function() {
- // proxy used to establish prototype chain
- var F = function() {};
- // extend Child from Parent
- return function(Child, Parent) {
- F.prototype = Parent.prototype;
- Child.prototype = new F();
- Child.__super__ = Parent.prototype;
- Child.prototype.constructor = Child;
- };
- }()),
-
- /**
- * Alerts a message in any available way: alert or console.log.
- */
- alert:function(msg) {
- if (alert) {
- alert(msg);
- } else if (console && console.log) {
- console.log(msg);
- }
+ switch(formatChar) {
+ case 'j':
+ case 'o': return JSON.stringify(object)
+ case 'c': return ''
}
-};
-module.exports = _self;
+ if (null == object) return Object.prototype.toString.call(object)
+
+ return object.toString()
+}
View
75 test/test.utils.js
@@ -92,4 +92,79 @@ describe("utils", function () {
expect(uuid).toMatch(/^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/);
expect(uuid).not.toEqual(utils.createUUID());
});
+
+ describe("format() method", function () {
+ it("handles passing nothing", function() {
+ expect(utils.format()).toBe("")
+ })
+
+ it("handles the empty string", function() {
+ expect(utils.format("")).toBe("")
+ })
+
+ it("handles null", function() {
+ expect(utils.format(null)).toBe("")
+ })
+
+ it("handles undefined", function() {
+ expect(utils.format(undefined)).toBe("")
+ })
+
+ it("handles NaN", function() {
+ expect(utils.format(1/'x')).toBe('NaN')
+ })
+
+ it("handles Infinity", function() {
+ expect(utils.format(1/0)).toBe('Infinity')
+ })
+
+ it("handles ('x')", function() {
+ expect(utils.format('x')).toBe('x')
+ })
+
+ it("handles ('x',1)", function() {
+ expect(utils.format('x',1)).toBe('x')
+ })
+
+ it("handles ('%d',1)", function() {
+ expect(utils.format('%d',1)).toBe('1')
+ })
+
+ it("handles ('%d','x')", function() {
+ expect(utils.format('%d','x')).toBe('x')
+ })
+
+ it("handles ('%s %s %s',1,2,3)", function() {
+ expect(utils.format('%s %s %s',1,2,3)).toBe('1 2 3')
+ })
+
+ it("handles ('1%c2%c3',1,2,3)", function() {
+ expect(utils.format('1%c2%c3',1,2,3)).toBe('123')
+ })
+
+ it("handles ('%j',{a:1})", function() {
+ expect(utils.format('%j',{a:1})).toBe('{"a":1}')
+ })
+
+ it("handles ('%d: %o',1, {b:2})", function() {
+ expect(utils.format('%d: %j',1, {b:2})).toBe('1: {"b":2}')
+ })
+
+ it("handles ('%j',function(){})", function() {
+ expect(utils.format('%j',function(){})).toBe('')
+ })
+
+ it("handles ('%s',function(){})", function() {
+ expect(utils.format('%s',function(){})).toBe('function (){}')
+ })
+
+ it("handles ('1%%2%%3',4)", function() {
+ expect(utils.format('1%%2%%3',1)).toBe('1%2%3')
+ })
+
+ it("handles ('1%x2%y3',4,5)", function() {
+ expect(utils.format('1%x2%y3',4,5)).toBe('14253')
+ })
+ })
+
});

0 comments on commit 2da5b44

Please sign in to comment.
Something went wrong with that request. Please try again.