rspec-web 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. data/Gemfile.lock +1 -1
  2. data/VERSION +1 -1
  3. data/bin/rspec-web +1 -1
  4. data/lib/rspec_web/web_application.rb +6 -0
  5. data/lib/rspec_web/web_application/public/js/lib/backbone.js +37 -0
  6. data/lib/rspec_web/web_application/public/js/{bootstrap.js → lib/bootstrap.js} +0 -0
  7. data/lib/rspec_web/web_application/public/js/{date.js → lib/date.js} +0 -0
  8. data/lib/rspec_web/web_application/public/js/{jquery.cookie.js → lib/jquery.cookie.js} +0 -0
  9. data/lib/rspec_web/web_application/public/js/{jquery.gracefulWebSocket.js → lib/jquery.gracefulWebSocket.js} +0 -0
  10. data/lib/rspec_web/web_application/public/js/{jquery.js → lib/jquery.js} +0 -0
  11. data/lib/rspec_web/web_application/public/js/{jquery.json.js → lib/jquery.json.js} +0 -0
  12. data/lib/rspec_web/web_application/public/js/lib/underscore.js +31 -0
  13. data/lib/rspec_web/web_application/public/js/models/example.js +3 -0
  14. data/lib/rspec_web/web_application/public/js/models/exampleCollection.js +25 -0
  15. data/lib/rspec_web/web_application/public/js/models/iteration.js +56 -0
  16. data/lib/rspec_web/web_application/public/js/models/iterationCollection.js +39 -0
  17. data/lib/rspec_web/web_application/public/js/models/project.js +0 -0
  18. data/lib/rspec_web/web_application/public/js/models/viewContainer.js +14 -0
  19. data/lib/rspec_web/web_application/public/js/models/webSocketContainer.js +46 -0
  20. data/lib/rspec_web/web_application/public/js/rspecWebFrontend.js +11 -0
  21. data/lib/rspec_web/web_application/public/js/script.js +4 -202
  22. data/lib/rspec_web/web_application/views/index.haml +21 -79
  23. data/lib/rspec_web/web_application/views/partials/example_entry.haml +10 -0
  24. data/lib/rspec_web/web_application/views/partials/iteration_entry.haml +31 -0
  25. data/lib/rspec_web/web_application/views/partials/iteration_list_entry.haml +4 -0
  26. metadata +40 -28
  27. data/lib/rspec_web/web_application/public/js/tmpl.js +0 -35
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-web (0.1.5)
4
+ rspec-web (0.1.9)
5
5
  em-websocket (~> 0.3.6)
6
6
  haml (~> 3.1.4)
7
7
  rspec (~> 2.8.0)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.9
1
+ 0.1.10
data/bin/rspec-web CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  require 'spork/runner'
12
12
 
13
13
  Thread.new { Spork::Runner.run(ARGV, STDOUT, STDERR) }
14
- rescue; end
14
+ rescue LoadError; end
15
15
 
16
16
  RspecWeb::WebSocketServer.run!
17
17
  RspecWeb::WebApplication.run!
@@ -13,6 +13,12 @@ module RspecWeb
13
13
  enable :method_override
14
14
  end
15
15
 
16
+ helpers do
17
+ def partial(name)
18
+ haml(:"partials/#{name}", layout: false, escape_attrs: false)
19
+ end
20
+ end
21
+
16
22
  get '/css/style.css' do
17
23
  scss :style
18
24
  end
@@ -0,0 +1,37 @@
1
+ // Backbone.js 0.9.1
2
+
3
+ // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
4
+ // Backbone may be freely distributed under the MIT license.
5
+ // For all details and documentation:
6
+ // http://backbonejs.org
7
+ (function(){var i=this,r=i.Backbone,s=Array.prototype.slice,t=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:i.Backbone={};g.VERSION="0.9.1";var f=i._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var h=i.jQuery||i.Zepto||i.ender;g.setDomLibrary=function(a){h=a};g.noConflict=function(){i.Backbone=r;return this};g.emulateHTTP=!1;g.emulateJSON=!1;g.Events={on:function(a,b,c){for(var d,a=a.split(/\s+/),e=this._callbacks||(this._callbacks={});d=a.shift();){d=e[d]||(e[d]=
8
+ {});var f=d.tail||(d.tail=d.next={});f.callback=b;f.context=c;d.tail=f.next={}}return this},off:function(a,b,c){var d,e,f;if(a){if(e=this._callbacks)for(a=a.split(/\s+/);d=a.shift();)if(f=e[d],delete e[d],b&&f)for(;(f=f.next)&&f.next;)if(!(f.callback===b&&(!c||f.context===c)))this.on(d,f.callback,f.context)}else delete this._callbacks;return this},trigger:function(a){var b,c,d,e;if(!(d=this._callbacks))return this;e=d.all;for((a=a.split(/\s+/)).push(null);b=a.shift();)e&&a.push({next:e.next,tail:e.tail,
9
+ event:b}),(c=d[b])&&a.push({next:c.next,tail:c.tail});for(e=s.call(arguments,1);c=a.pop();){b=c.tail;for(d=c.event?[c.event].concat(e):e;(c=c.next)!==b;)c.callback.apply(c.context||this,d)}return this}};g.Events.bind=g.Events.on;g.Events.unbind=g.Events.off;g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=j(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");if(!this.set(a,
10
+ {silent:!0}))throw Error("Can't create an invalid model");delete this._changed;this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(g.Model.prototype,g.Events,{idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.attributes[a];return this._escapedAttributes[a]=f.escape(null==b?"":""+b)},has:function(a){return null!=
11
+ this.attributes[a]},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof g.Model&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=this.attributes,k=this._escapedAttributes,n=this._previousAttributes||{},h=this._setting;this._changed||(this._changed={});this._setting=!0;for(e in d)if(a=d[e],f.isEqual(b[e],a)||delete k[e],c.unset?delete b[e]:b[e]=
12
+ a,this._changing&&!f.isEqual(this._changed[e],a)&&(this.trigger("change:"+e,this,a,c),this._moreChanges=!0),delete this._changed[e],!f.isEqual(n[e],a)||f.has(b,e)!=f.has(n,e))this._changed[e]=a;h||(!c.silent&&this.hasChanged()&&this.change(c),this._setting=!1);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,
13
+ e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};c.wait&&(e=f.clone(this.attributes));a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var k=this,h=c.success;c.success=function(a,b,e){b=k.parse(a,e);c.wait&&(b=f.extend(d||{},b));if(!k.set(b,c))return!1;h?h(k,a):k.trigger("sync",k,a,c)};c.error=g.wrapError(c.error,
14
+ k,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d();a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=j(this.collection,"url")||j(this,"urlRoot")||o();return this.isNew()?
15
+ a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){if(this._changing||!this.hasChanged())return this;this._moreChanges=this._changing=!0;for(var b in this._changed)this.trigger("change:"+b,this,this._changed[b],a);for(;this._moreChanges;)this._moreChanges=!1,this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);
16
+ delete this._changed;this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this._changed):this._changed&&f.has(this._changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this._changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},
17
+ isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});g.Collection=function(a,b){b||(b={});b.comparator&&(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(g.Collection.prototype,g.Events,{model:g.Model,initialize:function(){},
18
+ toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){var c,d,e,g,h,i={},j={};b||(b={});a=f.isArray(a)?a.slice():[a];for(c=0,d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");if(i[g=e.cid]||this._byCid[g]||null!=(h=e.id)&&(j[h]||this._byId[h]))throw Error("Can't add the same model to a collection twice");i[g]=j[h]=e}for(c=0;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=
19
+ e.id&&(this._byId[e.id]=e);this.length+=d;t.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;for(c=0,d=this.models.length;c<d;c++)if(i[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?a.slice():[a];for(c=0,d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,
20
+ 1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},get:function(a){return null==a?null:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length?this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",
21
+ this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,{silent:!0,parse:b.parse});b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,
22
+ b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){a instanceof g.Model?a.collection||
23
+ (a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),
24
+ function(a){g.Collection.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)};var u=/:\w+/g,v=/\*\w+/g,w=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(g.Router.prototype,g.Events,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new g.History);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=
25
+ this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(w,"\\$&").replace(u,"([^/]+)").replace(v,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,
26
+ b){return a.exec(b).slice(1)}});g.History=function(){this.handlers=[];f.bindAll(this,"checkUrl")};var m=/^[#\/]/,x=/msie [\w.]+/,l=!1;f.extend(g.History.prototype,g.Events,{interval:50,getFragment:function(a,b){if(null==a)if(this._hasPushState||b){var a=window.location.pathname,c=window.location.search;c&&(a+=c)}else a=window.location.hash;a=decodeURIComponent(a);a.indexOf(this.options.root)||(a=a.substr(this.options.root.length));return a.replace(m,"")},start:function(a){if(l)throw Error("Backbone.history has already been started");
27
+ this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=x.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b))this.iframe=h('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);this._hasPushState?h(window).bind("popstate",
28
+ this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?h(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;l=!0;a=window.location;b=a.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;this._wantsPushState&&this._hasPushState&&b&&a.hash&&
29
+ (this.fragment=a.hash.replace(m,""),window.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},stop:function(){h(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);l=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.iframe.location.hash));
30
+ if(a==this.fragment||a==decodeURIComponent(this.fragment))return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(window.location.hash)},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!l)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(m,"");this.fragment==c||this.fragment==decodeURIComponent(c)||(this._hasPushState?(0!=c.indexOf(this.options.root)&&(c=
31
+ this.options.root+c),this.fragment=c,window.history[b.replace?"replaceState":"pushState"]({},document.title,c)):this._wantsHashChange?(this.fragment=c,this._updateHash(window.location,c,b.replace),this.iframe&&c!=this.getFragment(this.iframe.location.hash)&&(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,c,b.replace))):window.location.assign(this.options.root+a),b.trigger&&this.loadUrl(a))},_updateHash:function(a,b,c){c?a.replace(a.toString().replace(/(javascript:|#).*$/,
32
+ "")+"#"+b):a.hash=b}});g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var y=/^(\S+)\s*(.*)$/,p="model,collection,el,id,attributes,className,tagName".split(",");f.extend(g.View.prototype,g.Events,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);
33
+ b&&h(a).attr(b);c&&h(a).html(c);return a},setElement:function(a,b){this.$el=h(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=j(this,"events"))){this.undelegateEvents();for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Event "'+a[b]+'" does not exist');var d=b.match(y),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+
34
+ this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=p.length;b<c;b++){var d=p[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,!1);else{var a=j(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});g.Model.extend=g.Collection.extend=g.Router.extend=g.View.extend=function(a,b){var c=z(this,a,b);c.extend=this.extend;return c};
35
+ var A={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=A[a],e={type:d,dataType:"json"};c.url||(e.url=j(b,"url")||o());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json",e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",
36
+ d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return h.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var q=function(){},z=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);q.prototype=a.prototype;d.prototype=new q;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},j=function(a,b){return!a||!a[b]?
37
+ null:f.isFunction(a[b])?a[b]():a[b]},o=function(){throw Error('A "url" property or function must be specified');}}).call(this);
@@ -0,0 +1,31 @@
1
+ // Underscore.js 1.3.1
2
+ // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3
+ // Underscore is freely distributable under the MIT license.
4
+ // Portions of Underscore are inspired or borrowed from Prototype,
5
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
+ // For all details and documentation:
7
+ // http://documentcloud.github.com/underscore
8
+ (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9
+ c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
10
+ h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
11
+ b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
12
+ null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
13
+ function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
14
+ e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15
+ function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
16
+ return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
17
+ c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
18
+ b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
19
+ return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
20
+ d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
21
+ var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
22
+ c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
23
+ a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
24
+ b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
25
+ 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
26
+ b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
27
+ b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
28
+ function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
29
+ u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
30
+ function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
31
+ true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
@@ -0,0 +1,3 @@
1
+ var Example = Backbone.Model.extend({
2
+
3
+ });
@@ -0,0 +1,25 @@
1
+ var ExampleCollection = function(iteration, exampleType) {
2
+ this.collection = [];
3
+ this.iteration = iteration;
4
+ this.exampleType = exampleType;
5
+
6
+ this.add = function(data) {
7
+ var timestamp = this.iteration.get('timestamp');
8
+
9
+ $.extend(data, { timestamp: timestamp, exampleIndex: this.finishedCount()-1 });
10
+
11
+ var template = _.template( $('#exampleEntry').html() );
12
+ var newExampleEntry = $( template(data) );
13
+
14
+ this.collection.push(newExampleEntry);
15
+
16
+ $('#iteration-'+timestamp+'-tab-content-'+this.exampleType).append(newExampleEntry);
17
+ $('#iteration-'+timestamp+'-tab-'+this.exampleType+'-count').html( this.finishedCount() );
18
+ $('#iteration-'+timestamp+'-finished-example-count').html( this.iteration.examples.finishedCount() );
19
+
20
+ this.iteration.updateProgressBar();
21
+ this.iteration.updateListEntryIcon();
22
+ };
23
+
24
+ this.finishedCount = function() { return this.collection.length; };
25
+ }
@@ -0,0 +1,56 @@
1
+ var Iteration = Backbone.Model.extend({
2
+ initialize : function() {
3
+ var self = this;
4
+
5
+ this.examples = {
6
+ passing : new ExampleCollection(self, 'passing'),
7
+ pending : new ExampleCollection(self, 'pending'),
8
+ failing : new ExampleCollection(self, 'failing'),
9
+ finishedCount : function() { return self.examples.passing.finishedCount() + self.examples.pending.finishedCount() + self.examples.failing.finishedCount(); }
10
+ }
11
+ },
12
+ updateListEntryIcon : function() {
13
+ var listEntryIconElement = $('#iteration-'+this.get('timestamp')+'-list-entry-icon');
14
+ var newListEntryIconClass;
15
+
16
+ if (this.examples.passing.finishedCount() > 0){ newListEntryIconClass = 'icon-ok-sign'; }
17
+ if (this.examples.pending.finishedCount() > 0){ newListEntryIconClass = 'icon-question-sign'; }
18
+ if (this.examples.failing.finishedCount() > 0){ newListEntryIconClass = 'icon-remove-sign'; }
19
+
20
+ if ( !listEntryIconElement.hasClass(newListEntryIconClass) ){
21
+ listEntryIconElement.removeClass('icon-info-sign');
22
+ listEntryIconElement.removeClass('icon-ok-sign');
23
+ listEntryIconElement.removeClass('icon-question-sign');
24
+ listEntryIconElement.removeClass('icon-remove-sign');
25
+
26
+ listEntryIconElement.addClass(newListEntryIconClass);
27
+ }
28
+ },
29
+ updateProgressBar : function(){
30
+ var timestamp = this.get('timestamp');
31
+ var percentageComplete = (this.examples.finishedCount() / this.get('exampleCount')) * 100;
32
+ var progressRowElement = $('#iteration-'+timestamp+'-progress-row');
33
+ var progressContainerElement = $('#iteration-'+timestamp+'-progress-container');
34
+ var progressBarElement = $('#iteration-'+timestamp+'-progress-bar');
35
+ var newProgressBarClass;
36
+
37
+ progressBarElement.css('width', percentageComplete + '%');
38
+
39
+ if (this.examples.passing.finishedCount() > 0){ newProgressBarClass = 'progress-passing'; }
40
+ if (this.examples.pending.finishedCount() > 0){ newProgressBarClass = 'progress-pending'; }
41
+ if (this.examples.failing.finishedCount() > 0){ newProgressBarClass = 'progress-failing'; }
42
+
43
+ if ( !progressContainerElement.hasClass(newProgressBarClass) ){
44
+ progressContainerElement.removeClass('progress-passing');
45
+ progressContainerElement.removeClass('progress-pending');
46
+ progressContainerElement.removeClass('progress-failing');
47
+
48
+ progressContainerElement.addClass(newProgressBarClass);
49
+ }
50
+
51
+ if (percentageComplete == 100){
52
+ progressContainerElement.removeClass('active');
53
+ progressContainerElement.removeClass('progress-striped');
54
+ }
55
+ }
56
+ });
@@ -0,0 +1,39 @@
1
+ // var IterationCollection = function(max) {
2
+ var IterationCollection = function(rspecWebFrontend) {
3
+ this.collection = {};
4
+ // this.max = max;
5
+
6
+ this.add = function(timestamp, exampleCount) {
7
+ $('#btn-run-specs').removeAttr('disabled');
8
+
9
+ var templateVariables = {
10
+ timestamp : timestamp,
11
+ exampleCount : exampleCount,
12
+ formattedTimestamp : new Date(timestamp*1000).toString('ddd MMM d h:mm:ss tt'),
13
+ iterationsCount : this.collection.length
14
+ };
15
+
16
+ var firstIterationListEntry = $('#iterationsList').children()[0]; // Iterations header
17
+
18
+ var newIterationListEntryTemplate = _.template( $('#iterationListEntry').html() );
19
+ var newIterationListEntry = $( newIterationListEntryTemplate(templateVariables) );
20
+
21
+ var newIterationEntryTemplate = _.template( $('#iterationEntry').html() );
22
+ var newIterationEntry = $( newIterationEntryTemplate(templateVariables) );
23
+
24
+ $('#iterations').prepend(newIterationEntry);
25
+
26
+ newIterationListEntry.insertAfter(firstIterationListEntry);
27
+ newIterationListEntry.popover( rspecWebFrontend.iterations.newIterationListEntryPopoverOptions );
28
+
29
+ rspecWebFrontend.views.show('iterations');
30
+
31
+ newIterationListEntry.addClass('active');
32
+ newIterationEntry.addClass('active');
33
+ newIterationListEntry.slideDown();
34
+
35
+ this.collection[timestamp] = new Iteration({ timestamp : timestamp, exampleCount : exampleCount });
36
+ };
37
+
38
+ this.count = function() { return this.collection.length; };
39
+ }
@@ -0,0 +1,14 @@
1
+ var ViewContainer = function(rspecWebFrontend, opts) {
2
+ this.currentName = opts.initialView;
3
+ this.show = function() {
4
+ var viewName = arguments[0].replace(/View$/, '');
5
+ var callback = arguments[1];
6
+
7
+ $('#'+this.currentName+'View').fadeOut(function(){
8
+ $('#'+viewName+'View').fadeIn();
9
+ if (typeof callback != 'undefined'){ callback(); }
10
+ });
11
+
12
+ this.currentName = viewName;
13
+ };
14
+ };
@@ -0,0 +1,46 @@
1
+ var WebSocketContainer = function(rspecWebFrontend, opts) {
2
+ this.host = opts.host;
3
+ this.port = opts.port;
4
+ this.socket = $.gracefulWebSocket('ws://'+this.host+':'+this.port);
5
+ this.socket.onmessage = function(messageEvent){
6
+ var message = $.parseJSON(messageEvent.data);
7
+ var timestamp = message["arguments"][0];
8
+
9
+ if (message["method"] == "startNewIteration"){
10
+ var exampleCount = message["arguments"][1];
11
+
12
+ rspecWebFrontend.iterations.add(timestamp, exampleCount);
13
+ } else if (message["method"] == "addToPassing" || message["method"] == "addToPending" || message["method"] == "addToFailing"){
14
+ var data = message["arguments"][1];
15
+
16
+ if (message["method"] == "addToPassing") {
17
+ rspecWebFrontend.iterations.collection[timestamp].examples.passing.add(data);
18
+ } else if (message["method"] == "addToPending") {
19
+ rspecWebFrontend.iterations.collection[timestamp].examples.pending.add(data);
20
+ } else if (message["method"] == "addToFailing") {
21
+ rspecWebFrontend.iterations.collection[timestamp].examples.failing.add(data);
22
+ }
23
+ }
24
+ };
25
+
26
+ this.identify = function() {
27
+ this.socket.send( $.toJSON({
28
+ receiver : "server",
29
+ method : "identify",
30
+ arguments : ["web"]
31
+ }) );
32
+ };
33
+
34
+ this.runSpecs = function() {
35
+ var settingsRspecCommand = $.cookie('settingsRspecCommand');
36
+ if (settingsRspecCommand == '' || typeof settingsRspecCommand == 'undefined') {
37
+ settingsRspecCommand = rspecWebFrontend.config.defaultCommand;
38
+ }
39
+
40
+ this.socket.send( $.toJSON({
41
+ receiver : "server",
42
+ method : "runSpecs",
43
+ arguments : [ settingsRspecCommand ]
44
+ }) );
45
+ };
46
+ };
@@ -0,0 +1,11 @@
1
+ var rspecWebFrontend = {
2
+ config : {
3
+ defaultCommand : 'rspec spec --f RspecWeb::Formatter --drb'
4
+ }
5
+ };
6
+
7
+ $(function() {
8
+ rspecWebFrontend.webSocket = new WebSocketContainer(rspecWebFrontend, { host: window.location.hostname, port: 10081 });
9
+ rspecWebFrontend.views = new ViewContainer(rspecWebFrontend, { initialView: 'noIterationsError' });
10
+ rspecWebFrontend.iterations = new IterationCollection(rspecWebFrontend);
11
+ });
@@ -1,198 +1,12 @@
1
- function Iteration(timestamp, exampleCount, iterationEntry) {
2
- var self = this;
3
-
4
- this.passingExamples = [];
5
- this.pendingExamples = [];
6
- this.failingExamples = [];
7
- this.timestamp = timestamp;
8
- this.totalExampleCount = exampleCount;
9
- this.iterationEntry = iterationEntry;
10
-
11
- this.addMethods = {
12
- // TODO: merge into one method
13
- addToPassing : function(data){
14
- $.extend(data, { timestamp: timestamp, exampleIndex: self.finishedExampleCount()-1 });
15
- var newExampleEntry = $( tmpl("exampleEntry", data) );
16
- self.passingExamples.push(newExampleEntry);
17
- $('#iteration-'+timestamp+'-tab-content-passing').append(newExampleEntry);
18
- $('#iteration-'+timestamp+'-tab-passing-count').html(self.passingExamples.length);
19
- self.updateProgressBar();
20
- self.updateListEntryIcon();
21
- $('#finishedExampleCount').html( self.finishedExampleCount() );
22
- },
23
- addToPending : function(data){
24
- $.extend(data, { timestamp: timestamp, exampleIndex: self.finishedExampleCount()-1 });
25
- var newExampleEntry = $( tmpl("exampleEntry", data) );
26
- self.pendingExamples.push(newExampleEntry);
27
- $('#iteration-'+timestamp+'-tab-content-pending').append(newExampleEntry);
28
- $('#iteration-'+timestamp+'-tab-pending-count').html(self.pendingExamples.length);
29
- self.updateProgressBar();
30
- self.updateListEntryIcon();
31
- $('#finishedExampleCount').html( self.finishedExampleCount() );
32
- },
33
- addToFailing : function(data){
34
- $.extend(data, { timestamp: timestamp, exampleIndex: self.finishedExampleCount()-1 });
35
- var newExampleEntry = $( tmpl("exampleEntry", data) );
36
- self.failingExamples.push(newExampleEntry);
37
- $('#iteration-'+timestamp+'-tab-content-failing').append(newExampleEntry);
38
- $('#iteration-'+timestamp+'-tab-failing-count').html(self.failingExamples.length);
39
- self.updateProgressBar();
40
- self.updateListEntryIcon();
41
- $('#finishedExampleCount').html( self.finishedExampleCount() );
42
- }
43
- };
44
-
45
- this.finishedExampleCount = function(){
46
- return self.passingExamples.length + self.pendingExamples.length + self.failingExamples.length;
47
- };
48
-
49
- this.updateListEntryIcon = function(){
50
- var listEntryIconElement = $('#iteration-'+timestamp+'-list-entry-icon');
51
- var newListEntryIconClass;
52
-
53
- if (this.passingExamples.length > 0){ newListEntryIconClass = 'icon-ok-sign'; }
54
- if (this.pendingExamples.length > 0){ newListEntryIconClass = 'icon-question-sign'; }
55
- if (this.failingExamples.length > 0){ newListEntryIconClass = 'icon-remove-sign'; }
56
-
57
- if ( !listEntryIconElement.hasClass(newListEntryIconClass) ){
58
- listEntryIconElement.removeClass('icon-info-sign');
59
- listEntryIconElement.removeClass('icon-ok-sign');
60
- listEntryIconElement.removeClass('icon-question-sign');
61
- listEntryIconElement.removeClass('icon-remove-sign');
62
-
63
- listEntryIconElement.addClass(newListEntryIconClass);
64
- }
65
- };
66
-
67
- this.updateProgressBar = function(){
68
- var percentageComplete = (this.finishedExampleCount() / this.totalExampleCount) * 100;
69
- var progressRowElement = $('#iteration-'+timestamp+'-progress-row');
70
- var progressContainerElement = $('#iteration-'+timestamp+'-progress-container');
71
- var progressBarElement = $('#iteration-'+timestamp+'-progress-bar');
72
- var newProgressBarClass;
73
-
74
- progressBarElement.css('width', percentageComplete + '%');
75
-
76
- if (this.passingExamples.length > 0){ newProgressBarClass = 'progress-passing'; }
77
- if (this.pendingExamples.length > 0){ newProgressBarClass = 'progress-pending'; }
78
- if (this.failingExamples.length > 0){ newProgressBarClass = 'progress-failing'; }
79
-
80
- if ( !progressContainerElement.hasClass(newProgressBarClass) ){
81
- progressContainerElement.removeClass('progress-passing');
82
- progressContainerElement.removeClass('progress-pending');
83
- progressContainerElement.removeClass('progress-failing');
84
-
85
- progressContainerElement.addClass(newProgressBarClass);
86
- }
87
-
88
- if (percentageComplete == 100){
89
- progressContainerElement.removeClass('active');
90
- progressContainerElement.removeClass('progress-striped');
91
- }
92
- };
93
- }
94
-
95
- var rspecWebFrontend; // Makes rspecWebFrontend accessable to console
96
-
97
1
  $(function(){
98
2
  var $iterationsListContainer = $('#iterationsListContainer');
99
3
  var $iterationsList = $("#iterationsList");
100
4
  var $iterationsContainer = $('#iterationsContainer');
101
5
  var $iterations = $("#iterations");
102
- var preSettingsView;
103
-
104
- rspecWebFrontend = {
105
- config : {
106
- defaultCommand : 'rspec spec --f RspecWeb::Formatter --drb'
107
- },
108
- webSocket : $.gracefulWebSocket('ws://'+window.location.hostname+':10081'),
109
- views : {
110
- currentName : 'noIterationsError',
111
- show : function(viewName){
112
- var viewName, callback;
113
- viewName = arguments[0].replace(/View$/, '');
114
- callback = arguments[1];
115
-
116
- $('#'+rspecWebFrontend.views.currentName+'View').fadeOut(function(){
117
- $('#'+viewName+'View').fadeIn();
118
- if (typeof callback != 'undefined'){ callback(); }
119
- });
120
-
121
- rspecWebFrontend.views.currentName = viewName;
122
- }
123
- },
124
- iterations : {
125
- list : {},
126
- max : 5,
127
- newIterationListEntryPopoverOptions : {
128
- placement : 'right',
129
- trigger : 'manual',
130
- title : 'New iteration',
131
- content : '<p>Running new iteration!</p><p>Click here to view it.</p>'
132
- },
133
-
134
- startNewIteration : function(timestamp, exampleCount){
135
- $('#btn-run-specs').removeAttr('disabled');
136
-
137
- var templateVariables = {
138
- timestamp : timestamp,
139
- exampleCount : exampleCount,
140
- formattedTimestamp : new Date(timestamp*1000).toString('ddd MMM d h:mm:ss tt'),
141
- iterationsCount : rspecWebFrontend.iterations.list.length
142
- };
143
-
144
- var firstIterationListEntry = $iterationsList.children()[0]; // Iterations header
145
-
146
- var newIterationListEntry = $( tmpl("iterationListEntry", templateVariables) );
147
- var newIterationEntry = $( tmpl("iterationEntry", templateVariables) );
148
-
149
- $iterations.prepend(newIterationEntry);
150
-
151
- newIterationListEntry.insertAfter(firstIterationListEntry);
152
- newIterationListEntry.popover( rspecWebFrontend.iterations.newIterationListEntryPopoverOptions );
153
-
154
- if ($.isEmptyObject(rspecWebFrontend.iterations.list)){
155
- rspecWebFrontend.views.show('iterations');
156
-
157
- newIterationListEntry.addClass('active');
158
- newIterationEntry.addClass('active');
159
- newIterationListEntry.slideDown();
160
- } else {
161
- newIterationListEntry.slideDown(function(){
162
- newIterationListEntry.popover('show');
163
- setTimeout(function() { newIterationListEntry.popover('hide'); }, 2000);
164
- });
165
- }
166
-
167
- rspecWebFrontend.iterations.list[timestamp] = new Iteration(timestamp, exampleCount, newIterationEntry);
168
- }
169
- }
170
- };
171
-
172
- // ===--- Socket - Start ---------------------------------------=== \\
173
- rspecWebFrontend.webSocket.onmessage = function(messageEvent){
174
- var message = $.parseJSON(messageEvent.data);
175
-
176
- if (message["method"] == "startNewIteration"){
177
- var timestamp = message["arguments"][0];
178
- var exampleCount = message["arguments"][1];
179
-
180
- rspecWebFrontend.iterations.startNewIteration(timestamp, exampleCount);
181
- } else if (message["method"] == "addToPassing" || message["method"] == "addToPending" || message["method"] == "addToFailing"){
182
- var timestamp = message["arguments"][0];
183
- var data = message["arguments"][1];
184
-
185
- rspecWebFrontend.iterations.list[timestamp].addMethods[ message["method"] ](data);
186
- }
187
- };
6
+ var $iterationEntry = $("#iterationEntry");
7
+ var $iterationListEntry = $("#iterationListEntry");
188
8
 
189
- setTimeout(function() {
190
- rspecWebFrontend.webSocket.send( $.toJSON({
191
- receiver : "server",
192
- method : "identify",
193
- arguments : ["web"]
194
- }) );
195
- }, 1000);
9
+ setTimeout(function() { rspecWebFrontend.webSocket.identify(); }, 1000);
196
10
  // ===--- Socket - End -----------------------------------------=== \\
197
11
 
198
12
 
@@ -201,23 +15,13 @@ $(function(){
201
15
  var $self = $(this);
202
16
 
203
17
  if (typeof $self.attr('disabled') == 'undefined') {
204
- var settingsRspecCommand = $.cookie('settingsRspecCommand');
205
- if (settingsRspecCommand == '' || typeof settingsRspecCommand == 'undefined') {
206
- settingsRspecCommand = rspecWebFrontend.config.defaultCommand;
207
- }
208
-
209
- rspecWebFrontend.webSocket.send( $.toJSON({
210
- receiver : "server",
211
- method : "runSpecs",
212
- arguments : [ settingsRspecCommand ]
213
- }) );
18
+ rspecWebFrontend.webSocket.runSpecs();
214
19
 
215
20
  $self.attr('disabled', 'disabled');
216
21
  }
217
22
  });
218
23
 
219
24
  $('#btn-settings').mouseup(function(e){
220
- preSettingsView = rspecWebFrontend.views.currentName;
221
25
  // rspecWebFrontend.views.show('settings');
222
26
  $('#settings').slideDown();
223
27
  });
@@ -244,11 +48,9 @@ $(function(){
244
48
  if ($(window).width() < 768) {
245
49
  $iterationsListContainer.removeClass('span4');
246
50
  $iterationsContainer.removeClass('span8');
247
- rspecWebFrontend.iterations.newIterationListEntryPopoverOptions.placement = 'bottom';
248
51
  } else {
249
52
  $iterationsListContainer.addClass('span4');
250
53
  $iterationsContainer.addClass('span8');
251
- rspecWebFrontend.iterations.newIterationListEntryPopoverOptions.placement = 'right';
252
54
  }
253
55
  }
254
56
  fixIterationsTable();
@@ -25,78 +25,9 @@
25
25
  / %link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon" sizes="72x72")
26
26
  / %link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon" sizes="114x114")
27
27
 
28
- %script#iterationListEntry(type="text/html")
29
- :plain
30
- <li>
31
- <a href="#iteration-<%= timestamp %>" data-toggle="tab">
32
- <i class="icon-info-sign" id="iteration-<%= timestamp %>-list-entry-icon"></i>
33
- <%= formattedTimestamp %>
34
- </a>
35
- </li>
36
- %script#iterationEntry(type="text/html")
37
- :plain
38
- <div class="tab-pane iteration" id="iteration-<%= timestamp %>">
39
-
40
- <div class="row-fluid progress-container" id="iteration-<%= timestamp %>-progress-row">
41
- <div class="span12" style="padding-right: 10px;">
42
- <div class="progress progress-striped progress-passing active" id="iteration-<%= timestamp %>-progress-container">
43
- <div class="bar" id="iteration-<%= timestamp %>-progress-bar" style="width: 0%;"></div>
44
- </div>
45
- </div>
46
- </div>
47
-
48
- <div class="row-fluid">
49
- <div class="span12">
50
- <h6><span id="finishedExampleCount">0</span> of <%= exampleCount %> example<%= exampleCount > 1 ? "s" : "" %> finished</h6>
51
- </div>
52
- </div>
53
-
54
- <div class="tabbable">
55
- <ul class="nav nav-tabs">
56
- <li class="active">
57
- <a href="#iteration-<%= timestamp %>-tab-content-passing" id="iteration-<%= timestamp %>-tab-passing" class="tab-passing" data-toggle="tab">
58
- Passing
59
- <span class="label label-passing" id="iteration-<%= timestamp %>-tab-passing-count">0</span>
60
- </a>
61
- </li>
62
- <li>
63
- <a href="#iteration-<%= timestamp %>-tab-content-pending" id="iteration-<%= timestamp %>-tab-pending" class="tab-pending" data-toggle="tab">
64
- Pending
65
- <span class="label label-pending" id="iteration-<%= timestamp %>-tab-pending-count">0</span>
66
- </a>
67
- </li>
68
- <li>
69
- <a href="#iteration-<%= timestamp %>-tab-content-failing" id="iteration-<%= timestamp %>-tab-failing" class="tab-failing" data-toggle="tab">
70
- Failing
71
- <span class="label label-failing" id="iteration-<%= timestamp %>-tab-failing-count">0</span>
72
- </a>
73
- </li>
74
- </ul>
75
-
76
- <div class="tab-content">
77
- <div class="tab-pane active" id="iteration-<%= timestamp %>-tab-content-passing"></div>
78
- <div class="tab-pane" id="iteration-<%= timestamp %>-tab-content-pending"></div>
79
- <div class="tab-pane" id="iteration-<%= timestamp %>-tab-content-failing"></div>
80
- </div>
81
- </div>
82
- </div>
83
- %script#exampleEntry(type="text/html")
84
- :plain
85
- <div class="accordion" id="iteration-<%= timestamp %>-accordion">
86
- <div class="accordion-group">
87
- <div class="accordion-heading">
88
- <a class="accordion-toggle" data-toggle="collapse" data-parent="#iteration-<%= timestamp %>-accordion" href="#iteration-<%= timestamp %>-example-<%= exampleIndex %>">
89
- <%= description %>
90
- </a>
91
- </div>
92
- <div class="accordion-body collapse" id="iteration-<%= timestamp %>-example-<%= exampleIndex %>" style="height: 0px;">
93
- <p>Started: <%= started_at %></p>
94
- <p>Finished: <%= finished_at %></p>
95
- <p>Run time: <%= run_time %></p>
96
- <p>Location: <%= file_path %>:<%= line_number %></p>
97
- </div>
98
- </div>
99
- </div>
28
+ %script#iterationListEntry(type="text/html")= partial(:iteration_list_entry)
29
+ %script#iterationEntry(type="text/html")= partial(:iteration_entry)
30
+ %script#exampleEntry(type="text/html")= partial(:example_entry)
100
31
  %body
101
32
  .navbar.navbar-fixed-top
102
33
  .navbar-inner
@@ -152,11 +83,22 @@
152
83
  %img(src="/img/bootstrap.png" width="25" height="25")
153
84
  .pull-right(style="margin-right: 10px;")
154
85
  %a(href="javascript:location.reload(true)") Refresh
155
- %script(type="text/javascript" src="/js/jquery.js")
156
- %script(type="text/javascript" src="/js/jquery.cookie.js")
157
- %script(type="text/javascript" src="/js/jquery.gracefulWebSocket.js")
158
- %script(type="text/javascript" src="/js/jquery.json.js")
159
- %script(type="text/javascript" src="/js/tmpl.js")
160
- %script(type="text/javascript" src="/js/date.js")
161
- %script(type="text/javascript" src="/js/bootstrap.js")
86
+
87
+ %script(type="text/javascript" src="/js/lib/jquery.js")
88
+ %script(type="text/javascript" src="/js/lib/jquery.cookie.js")
89
+ %script(type="text/javascript" src="/js/lib/jquery.gracefulWebSocket.js")
90
+ %script(type="text/javascript" src="/js/lib/jquery.json.js")
91
+ %script(type="text/javascript" src="/js/lib/underscore.js")
92
+ %script(type="text/javascript" src="/js/lib/backbone.js")
93
+ %script(type="text/javascript" src="/js/lib/bootstrap.js")
94
+ %script(type="text/javascript" src="/js/lib/date.js")
95
+
96
+ %script(type="text/javascript" src="/js/models/viewContainer.js")
97
+ %script(type="text/javascript" src="/js/models/webSocketContainer.js")
98
+ %script(type="text/javascript" src="/js/models/iterationCollection.js")
99
+ %script(type="text/javascript" src="/js/models/exampleCollection.js")
100
+ %script(type="text/javascript" src="/js/models/iteration.js")
101
+
102
+ %script(type="text/javascript" src="/js/rspecWebFrontend.js")
103
+
162
104
  %script(type="text/javascript" src="/js/script.js")
@@ -0,0 +1,10 @@
1
+ .accordion(id="iteration-<%= timestamp %>-accordion")
2
+ .accordion-group
3
+ .accordion-heading
4
+ %a.accordion-toggle(data-toggle="collapse" data-parent="#iteration-<%= timestamp %>-accordion" href="#iteration-<%= timestamp %>-example-<%= exampleIndex %>")
5
+ <%= description %>
6
+ .accordion-body.collapse(id="iteration-<%= timestamp %>-example-<%= exampleIndex %>" style="height: 0px;")
7
+ %p Started: <%= started_at %>
8
+ %p Finished: <%= finished_at %>
9
+ %p Run time: <%= run_time %>
10
+ %p Location: <%= file_path %>:<%= line_number %>
@@ -0,0 +1,31 @@
1
+ .tab-pane.iteration(id="iteration-<%= timestamp %>")
2
+ .row-fluid.progress-container(id="iteration-<%= timestamp %>-progress-row")
3
+ .span12(style="padding-right: 10px;")
4
+ .progress.progress-striped.progress-passing.active(id="iteration-<%= timestamp %>-progress-container")
5
+ .bar(id="iteration-<%= timestamp %>-progress-bar" style="width: 0%;")
6
+
7
+ .row-fluid
8
+ .span12
9
+ %h6
10
+ %span(id="iteration-<%= timestamp %>-finished-example-count") 0
11
+ of <%= exampleCount %> example<%= exampleCount > 1 ? "s" : "" %> finished
12
+
13
+ .tabbable
14
+ %ul.nav.nav-tabs
15
+ %li.active
16
+ %a.tab-passing(href="#iteration-<%= timestamp %>-tab-content-passing" id="iteration-<%= timestamp %>-tab-passing" data-toggle="tab")
17
+ Passing
18
+ %span.label.label-passing(id="iteration-<%= timestamp %>-tab-passing-count") 0
19
+ %li
20
+ %a.tab-pending(href="#iteration-<%= timestamp %>-tab-content-pending" id="iteration-<%= timestamp %>-tab-pending" data-toggle="tab")
21
+ Pending
22
+ %span.label.label-pending(id="iteration-<%= timestamp %>-tab-pending-count") 0
23
+ %li
24
+ %a.tab-failing(href="#iteration-<%= timestamp %>-tab-content-failing" id="iteration-<%= timestamp %>-tab-failing" data-toggle="tab")
25
+ Pending
26
+ %span.label.label-failing(id="iteration-<%= timestamp %>-tab-failing-count") 0
27
+
28
+ .tab-content
29
+ .tab-pane.active(id="iteration-<%= timestamp %>-tab-content-passing")
30
+ .tab-pane(id="iteration-<%= timestamp %>-tab-content-pending")
31
+ .tab-pane(id="iteration-<%= timestamp %>-tab-content-failing")
@@ -0,0 +1,4 @@
1
+ %li
2
+ %a(href="#iteration-<%= timestamp %>" data-toggle="tab")
3
+ %i.icon-info-sign(id="iteration-<%= timestamp %>-list-entry-icon")
4
+ <%= formattedTimestamp %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,74 +9,74 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-08 00:00:00.000000000Z
12
+ date: 2012-04-16 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-websocket
16
- requirement: &70260997872060 !ruby/object:Gem::Requirement
16
+ requirement: &70225502222660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.3.6
21
+ version: '0.3'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70260997872060
24
+ version_requirements: *70225502222660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: haml
27
- requirement: &70260997871200 !ruby/object:Gem::Requirement
27
+ requirement: &70225502222180 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 3.1.4
32
+ version: '3.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70260997871200
35
+ version_requirements: *70225502222180
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sass
38
- requirement: &70260997870460 !ruby/object:Gem::Requirement
38
+ requirement: &70225502221720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: 3.1.14
43
+ version: '3.1'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70260997870460
46
+ version_requirements: *70225502221720
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sinatra
49
- requirement: &70260997869520 !ruby/object:Gem::Requirement
49
+ requirement: &70225502221260 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: 1.3.2
54
+ version: '1.3'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70260997869520
57
+ version_requirements: *70225502221260
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &70260997868280 !ruby/object:Gem::Requirement
60
+ requirement: &70225502220800 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
64
64
  - !ruby/object:Gem::Version
65
- version: 2.8.0
65
+ version: '2.8'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70260997868280
68
+ version_requirements: *70225502220800
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: web-socket-ruby
71
- requirement: &70260997860260 !ruby/object:Gem::Requirement
71
+ requirement: &70225502220340 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
75
75
  - !ruby/object:Gem::Version
76
- version: 0.1.0
76
+ version: '0.1'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70260997860260
79
+ version_requirements: *70225502220340
80
80
  description: A web front-end for RSpec tests.
81
81
  email: c00lryguy@gmail.com
82
82
  executables:
@@ -97,15 +97,27 @@ files:
97
97
  - lib/rspec_web/web_application/public/img/glyphicons-halflings.png
98
98
  - lib/rspec_web/web_application/public/img/rails.png
99
99
  - lib/rspec_web/web_application/public/img/traffic.png
100
- - lib/rspec_web/web_application/public/js/bootstrap.js
101
- - lib/rspec_web/web_application/public/js/date.js
102
- - lib/rspec_web/web_application/public/js/jquery.cookie.js
103
- - lib/rspec_web/web_application/public/js/jquery.gracefulWebSocket.js
104
- - lib/rspec_web/web_application/public/js/jquery.js
105
- - lib/rspec_web/web_application/public/js/jquery.json.js
100
+ - lib/rspec_web/web_application/public/js/lib/backbone.js
101
+ - lib/rspec_web/web_application/public/js/lib/bootstrap.js
102
+ - lib/rspec_web/web_application/public/js/lib/date.js
103
+ - lib/rspec_web/web_application/public/js/lib/jquery.cookie.js
104
+ - lib/rspec_web/web_application/public/js/lib/jquery.gracefulWebSocket.js
105
+ - lib/rspec_web/web_application/public/js/lib/jquery.js
106
+ - lib/rspec_web/web_application/public/js/lib/jquery.json.js
107
+ - lib/rspec_web/web_application/public/js/lib/underscore.js
108
+ - lib/rspec_web/web_application/public/js/models/example.js
109
+ - lib/rspec_web/web_application/public/js/models/exampleCollection.js
110
+ - lib/rspec_web/web_application/public/js/models/iteration.js
111
+ - lib/rspec_web/web_application/public/js/models/iterationCollection.js
112
+ - lib/rspec_web/web_application/public/js/models/project.js
113
+ - lib/rspec_web/web_application/public/js/models/viewContainer.js
114
+ - lib/rspec_web/web_application/public/js/models/webSocketContainer.js
115
+ - lib/rspec_web/web_application/public/js/rspecWebFrontend.js
106
116
  - lib/rspec_web/web_application/public/js/script.js
107
- - lib/rspec_web/web_application/public/js/tmpl.js
108
117
  - lib/rspec_web/web_application/views/index.haml
118
+ - lib/rspec_web/web_application/views/partials/example_entry.haml
119
+ - lib/rspec_web/web_application/views/partials/iteration_entry.haml
120
+ - lib/rspec_web/web_application/views/partials/iteration_list_entry.haml
109
121
  - lib/rspec_web/web_application/views/style.scss
110
122
  - lib/rspec_web/web_application.rb
111
123
  - lib/rspec_web/web_socket_server.rb
@@ -133,6 +145,6 @@ rubyforge_project:
133
145
  rubygems_version: 1.8.10
134
146
  signing_key:
135
147
  specification_version: 3
136
- summary: Run and view RSpec tests from the browser.
148
+ summary: Run and view Rspec tests from the browser.
137
149
  test_files: []
138
150
  has_rdoc:
@@ -1,35 +0,0 @@
1
- // Simple JavaScript Templating
2
- // John Resig - http://ejohn.org/ - MIT Licensed
3
- (function(){
4
- var cache = {};
5
-
6
- this.tmpl = function tmpl(str, data){
7
- // Figure out if we're getting a template, or if we need to
8
- // load the template - and be sure to cache the result.
9
- var fn = !/\W/.test(str) ?
10
- cache[str] = cache[str] ||
11
- tmpl(document.getElementById(str).innerHTML) :
12
-
13
- // Generate a reusable function that will serve as a template
14
- // generator (and which will be cached).
15
- new Function("obj",
16
- "var p=[],print=function(){p.push.apply(p,arguments);};" +
17
-
18
- // Introduce the data as local variables using with(){}
19
- "with(obj){p.push('" +
20
-
21
- // Convert the template into pure JavaScript
22
- str
23
- .replace(/[\r\t\n]/g, " ")
24
- .split("<%").join("\t")
25
- .replace(/((^|%>)[^\t]*)'/g, "$1\r")
26
- .replace(/\t=(.*?)%>/g, "',$1,'")
27
- .split("\t").join("');")
28
- .split("%>").join("p.push('")
29
- .split("\r").join("\\'")
30
- + "');}return p.join('');");
31
-
32
- // Provide some basic currying to the user
33
- return data ? fn( data ) : fn;
34
- };
35
- })();