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