diff --git a/js-lib/jsDump.js b/js-lib/jsDump.js new file mode 100644 index 0000000..05b90f7 --- /dev/null +++ b/js-lib/jsDump.js @@ -0,0 +1,205 @@ +/** + * jsDump + * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com + * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php) + * Date: 5/15/2008 + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +var jsDump; + +(function(){ + function quote( str ){ + return '"' + str.toString().replace(/"/g, '\\"') + '"'; + } + function literal( o ){ + return o + ''; + } + function join( pre, arr, post ){ + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if( arr.join ) + arr = arr.join( ',' + s + inner ); + if( !arr ) + return pre + post; + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr ){ + var i = arr.length, ret = Array(i); + this.up(); + while( i-- ) + ret[i] = this.parse( arr[i] ); + this.down(); + return join( '[', ret, ']' ); + } + + var reName = /^function (\w+)/; + + jsDump = { + parse:function( obj, type ){//type is used mostly internally, you can fix a (custom)type in advance + var parser = this.parsers[ type || this.typeOf(obj) ]; + type = typeof parser; + + return type == 'function' ? parser.call( this, obj ) : + type == 'string' ? parser : + this.parsers.error; + }, + typeOf:function( obj ){ + var type = typeof obj, + kind; + + if ( type == 'object' || type == 'function' ) { + if ( obj === null ) + return 'null'; + + // Extract Staff from [Object Staff] + kind = Object.prototype.toString.call(obj).slice(8, -1); + switch ( kind ) { + case 'Array': + return 'array'; + + case 'Date': + return 'date'; + + case 'RegExp': + return 'regexp'; + + case 'Window': //Firefox, IE, Opera + case 'DOMWindow': //WebKit + case 'global': + return 'window'; + + case 'HTMLDocument': //WebKit, Firefox, Opera + case 'Document': // IE + return 'document'; + + case 'NodeList': + return 'nodelist'; + + default: + if ( 'callee' in obj ) + // Opera: Object.prototype.toString.call(arguments) == 'Object' :( + return 'arguments'; + else if ( 'ownerDocument' in obj && 'defaultView' in obj.ownerDocument && obj instanceof obj.ownerDocument.defaultView.Node ) + return 'node'; + } + } + return type; + }, + separator:function(){ + return this.multiline ? this.HTML ? '
' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ){// extra can be a number, shortcut for increasing-calling-decreasing + if( !this.multiline ) + return ''; + var chr = this.indentChar; + if( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ){ + this._depth_ += a || 1; + }, + down:function( a ){ + this._depth_ -= a || 1; + }, + setParser:function( name, parser ){ + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + undefined:'undefined', + 'function':function( fn ){ + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if( name ) + ret += ' ' + name; + ret += '('; + ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, this.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map ){ + var ret = [ ]; + this.up(); + var keys = []; + for (var key in map) { keys.push(key); } + keys = keys.sort(); + + for( var i = 0; i < keys.length; ++i ) { + var key = keys[i]; + if (!this.ignoreFunctions || this.typeOf(map[key]) != 'function') { + var value = "<< LOOP >>"; + + if (this.alreadySeenObjects.indexOf(map[key]) == -1) { + this.alreadySeenObjects.push(map[key]); + value = this.parse(map[key]); + } + + ret.push( this.parse(key,'key') + ': ' + value ); + } + } + this.down(); + return join( '{', ret, '}' ); + }, + node:function( node ){ + var open = this.HTML ? '<' : '<', + close = this.HTML ? '>' : '>'; + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + for( var a in this.DOMAttrs ){ + var val = node[this.DOMAttrs[a]]; + if( val ) + ret += ' ' + a + '=' + this.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ){//function calls it internally, it's the arguments part of the function + var l = fn.length; + if( !l ) return ''; + var args = Array(l); + while( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + alreadySeenObjects:[], + ignoreFunctions:true, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + +})(); + +if (typeof exports !== 'undefined') { + module.exports = jsDump; +} diff --git a/lib/jasmine/files_list.rb b/lib/jasmine/files_list.rb index fc482c8..922c59c 100644 --- a/lib/jasmine/files_list.rb +++ b/lib/jasmine/files_list.rb @@ -9,7 +9,8 @@ module Jasmine DEFAULT_FILES = [ File.join(Jasmine::Core.path, "jasmine.js"), File.join(Jasmine::Core.path, "jasmine-html.js"), - File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__) + File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__), + File.expand_path('../../../js-lib/jsDump.js', __FILE__) ] PLEASE_WAIT_IM_WORKING_TIME = 2 diff --git a/lib/jasmine/template_writer.rb b/lib/jasmine/template_writer.rb index e369f29..19d1a4f 100644 --- a/lib/jasmine/template_writer.rb +++ b/lib/jasmine/template_writer.rb @@ -29,9 +29,19 @@ module Jasmine