gerbil-rails 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,78 +1,135 @@
1
1
  //= require gerbil
2
2
  //= require jquery-1.7.1
3
3
 
4
- Gerbil.Rails = {
5
- formatter: (function($) {
6
- var currentScenario, ok, fail, pending;
7
-
8
- function test(text, className) {
9
- var li = $("<li/>").addClass(className).html(text);
10
- currentScenario.find("ul").append(li);
11
-
12
- currentScenario.
13
- removeClass("fail").
14
- removeClass("pending").
15
- removeClass("ok");
16
-
17
- if (fail > 0) {
18
- currentScenario.addClass("fail");
19
- } else if (pending > 0) {
20
- currentScenario.addClass("pending");
21
- } else if (ok > 0) {
22
- currentScenario.addClass("ok");
23
- }
24
- }
4
+ Gerbil.Rails = {}
25
5
 
26
- function pluralize(n, singular, plural) {
27
- if (typeof plural == "undefined")
28
- plural = singular + "s";
29
- return n == 1 ? [n, singular].join(" ") : [n, plural].join(" ");
30
- }
6
+ Gerbil.Rails.jQuery = jQuery.noConflict(true);
31
7
 
32
- return {
33
- scenario: function(msg) {
34
- ok = fail = pending = 0;
8
+ Gerbil.Rails.formatter = (function($) {
9
+ var currentScenario, status;
35
10
 
36
- currentScenario = $("<section/>");
37
- currentScenario.append("<h1>Running <strong>" + msg + "</strong></h1>");
38
- currentScenario.append("<ul/>");
11
+ function test(text, className) {
12
+ var li = $("<li/>").addClass(className).html(text);
13
+ currentScenario.find("ul").append(li);
39
14
 
40
- $("body").append(currentScenario);
41
- },
15
+ currentScenario.
16
+ removeClass("fail").
17
+ removeClass("pending").
18
+ removeClass("ok");
42
19
 
43
- summary: function(summary) {
44
- var msg, p = $("<p class='summary'/>"),
45
- time = Math.round(100 * summary.time) / 100;
20
+ if (status.fail > 0) {
21
+ currentScenario.addClass("fail");
22
+ } else if (status.pending > 0) {
23
+ currentScenario.addClass("pending");
24
+ } else if (status.ok > 0) {
25
+ currentScenario.addClass("ok");
26
+ }
27
+ }
28
+
29
+ function pluralize(n, singular, plural) {
30
+ if (typeof plural == "undefined")
31
+ plural = singular + "s";
32
+ return n == 1 ? [n, singular].join(" ") : [n, plural].join(" ");
33
+ }
34
+
35
+ return {
36
+ scenario: function(msg) {
37
+ status = { ok: 0, fail: 0, pending: 0 };
38
+
39
+ currentScenario = $("<section/>");
40
+ currentScenario.append("<h1>Running <strong>" + msg + "</strong></h1>");
41
+ currentScenario.append("<ul/>");
42
+
43
+ $("#results").append(currentScenario);
44
+ },
45
+
46
+ summary: function(summary) {
47
+ var msg, p = $("<p class='summary'/>"),
48
+ time = Math.round(100 * summary.time) / 100;
49
+
50
+ msg = [[summary.pass, "passed"].join(" "),
51
+ [summary.fail, "failed"].join(" "),
52
+ [summary.pending, "pending"].join(" ")].join(", ");
53
+
54
+ msg += " (" + summary.total + " total, " + pluralize(summary.assertions, "assertion") + ")";
55
+ msg += " in " + time + "s.";
56
+
57
+ p.text(msg);
58
+ currentScenario.append(p);
59
+ currentScenario.addClass("finished");
60
+ },
61
+
62
+ ok: function(msg) {
63
+ status.ok++
64
+ test(msg, "ok");
65
+ },
66
+
67
+ fail: function(msg) {
68
+ status.fail++
69
+ test(msg, "fail");
70
+ },
71
+
72
+ pending: function(msg) {
73
+ status.pending++
74
+ test(msg, "pending");
75
+ }
76
+ };
46
77
 
47
- msg = [[summary.pass, "passed"].join(" "),
48
- [summary.fail, "failed"].join(" "),
49
- [summary.pending, "pending"].join(" ")].join(", ");
78
+ })(Gerbil.Rails.jQuery);
50
79
 
51
- msg += " (" + summary.total + " total, " + pluralize(summary.assertions, "assertion") + ")";
52
- msg += " in " + time + "s.";
80
+ Gerbil.Rails.run = (function($) {
81
+ return function() {
82
+ function flashTitle(token, times) {
83
+ $("title").text(" spec runner");
53
84
 
54
- p.text(msg);
55
- currentScenario.append(p);
56
- currentScenario.addClass("finished");
57
- },
85
+ setTimeout(function() {
86
+ $("title").text(token + " spec runner");
87
+ }, 200);
58
88
 
59
- ok: function(msg) {
60
- ok += 1;
61
- test(msg, "ok");
62
- },
89
+ if (times == 0) return;
63
90
 
64
- fail: function(msg) {
65
- fail += 1;
66
- test(msg, "fail");
67
- },
91
+ setTimeout(function() {
92
+ flashTitle(token, times - 1);
93
+ }, 1000);
94
+ }
68
95
 
69
- pending: function(msg) {
70
- pending += 1;
71
- test(msg, "pending");
96
+ flashTitle("⌛", 0);
97
+ $.ajax({
98
+ url: "/assets/spec.js",
99
+ type: "GET",
100
+ dataType: "script",
101
+ success: function() {
102
+ $("#results").empty()
103
+ },
104
+ complete: function() {
105
+ setTimeout(function() {
106
+ var fail = $("section.fail").length,
107
+ pending = $("section.pending").length,
108
+ ok = $("section.ok").length;
109
+
110
+ if (fail > 0) {
111
+ flashTitle("✘", 2);
112
+ } else if (pending > 0) {
113
+ flashTitle("☯", 2);
114
+ } else if (ok > 0) {
115
+ flashTitle("✔", 2);
116
+ }
117
+ }, 0);
72
118
  }
73
- };
74
-
75
- })(jQuery.noConflict(true))
76
- };
119
+ });
120
+ }
121
+ })(Gerbil.Rails.jQuery);
77
122
 
78
123
  Gerbil.formatter = Gerbil.Rails.formatter;
124
+
125
+ Gerbil.Rails.jQuery(function($) {
126
+ var reload = $("#reload");
127
+
128
+ setInterval(function() {
129
+ if (!reload.is(":checked"))
130
+ return;
131
+ Gerbil.Rails.run();
132
+ }, 30000);
133
+
134
+ Gerbil.Rails.run();
135
+ });
@@ -4,6 +4,11 @@ html, body {
4
4
  font: 16px/1.5 Helvetica, Arial, sans-serif;
5
5
  }
6
6
 
7
+ .reload {
8
+ width: 800px;
9
+ margin: 16px auto;
10
+ }
11
+
7
12
  section {
8
13
  width: 800px;
9
14
  height: 100%;
@@ -2,12 +2,18 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf8">
5
- <title>Gerbil Spec Runner</title>
5
+ <title>⌛ spec sunner</title>
6
6
  <%= stylesheet_link_tag "gerbil/rails" %>
7
- <%= javascript_include_tag "gerbil/rails" %>
8
- <%= javascript_include_tag "spec" %>
9
7
  <%= csrf_meta_tags %>
10
8
  </head>
11
9
  <body>
10
+ <div class="reload">
11
+ <label for="reload">
12
+ <%= check_box_tag "reload", true, checked: true %>
13
+ Reload this page every 30 seconds?
14
+ </label>
15
+ </div>
16
+ <div id="results"></div>
17
+ <%= javascript_include_tag "gerbil/rails" %>
12
18
  </body>
13
19
  </html>
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.homepage = "http://github.com/foca/gerbil-rails"
9
9
  s.authors = ["Nicolas Sanguinetti"]
10
10
  s.email = "hi@nicolassanguinetti.info"
11
- s.version = "0.0.1"
11
+ s.version = "0.1.0"
12
12
  s.platform = Gem::Platform::RUBY
13
13
  s.add_dependency("rails")
14
14
  end
@@ -0,0 +1,57 @@
1
+ var Smoking = function(object, stubs) {
2
+ this.stubs = stubs;
3
+ this.extend = function(destination, source) {
4
+ for (var property in source) destination[property] = source[property];
5
+ return destination;
6
+ };
7
+
8
+ this.clone = function(object) { return this.extend({}, object); };
9
+
10
+ this.stub = function() {
11
+ var stubbedObject = new Object;
12
+ for(var arg in this.stubs) stubbedObject[arg] = this.stubs[arg];
13
+ this.extend(this.object, stubbedObject);
14
+ return this.object;
15
+ };
16
+
17
+ this.intercept = function(method, interceptFn) {
18
+ var originalFn = this.object[method];
19
+ if(typeof originalFn == 'function') {
20
+ this.object[method] = function() {
21
+ interceptFn();
22
+ var args = Array.prototype.slice.call(arguments);
23
+ originalFn.apply(this, args);
24
+ };
25
+ }
26
+ },
27
+
28
+ this.object = this.clone(object);
29
+ return typeof this.stubs != 'undefined' ? this.stub() : this;
30
+ };
31
+
32
+ Smoking.prototype = {
33
+ expects: function(callExpectations) {
34
+ if(typeof callExpectations == 'string') callExpectations = new Object()[callExpectations] = 1;
35
+ this.extend(this.object, { ___smoking_call_expectations: callExpectations });
36
+ for(var arg in callExpectations) {
37
+ if(!this.object[arg] || typeof this.object[arg] != 'function') return;
38
+ var self = this;
39
+ this.intercept(arg, function() { self.object.___smoking_call_expectations[arg]--; });
40
+ };
41
+ return this.object;
42
+ },
43
+
44
+ verify: function() {
45
+ if(!this.object.___smoking_call_expectations) throw new Error("No mocks defined");
46
+ var expectations = this.object.___smoking_call_expectations;
47
+ for(var arg in expectations)
48
+ if(expectations[arg] !== 0) throw new RangeError(arg + " needs to be called " + expectations[arg] + " times");
49
+ delete this.object.___smoking_call_expectations;
50
+ return true;
51
+ }
52
+
53
+ }
54
+
55
+ var smoking = function(obj, stubs) { return new Smoking(obj, stubs); };
56
+
57
+ if(typeof module != 'undefined') module.exports = smoking;
@@ -0,0 +1,116 @@
1
+ if(typeof module != 'undefined') {
2
+ var fs = require('fs');
3
+ var IS_NODE = true;
4
+ }
5
+
6
+ var VCRConstructor = function VCR() {
7
+ this.config = {
8
+ hookInto: null,
9
+ host: null,
10
+ cassetteLibraryDir: 'cassettes'
11
+ }
12
+ };
13
+
14
+ VCRConstructor.Store = {
15
+ set: function(dir, name, cassette) {
16
+ var data = JSON.stringify(cassette);
17
+ if(IS_NODE) {
18
+ fs.writeFile(dir + '/' + name + ".json", data);
19
+ } else {
20
+ localStorage.setItem(name, data);
21
+ }
22
+ },
23
+
24
+ get: function(dir, name) {
25
+ if(IS_NODE) {
26
+ try{
27
+ var data = fs.readFileSync(dir + '/' + name + ".json");
28
+ } catch(e) {
29
+ var data = false;
30
+ }
31
+ } else {
32
+ var data = localStorage.getItem(name);
33
+ }
34
+ return !data ? false : JSON.parse(data);
35
+ }
36
+ };
37
+
38
+ VCRConstructor.Context = function VCRContext(name, config) {
39
+ var self = this;
40
+
41
+ this.hookInto = config.hookInto;
42
+ this.cassetteLibraryDir = config.cassetteLibraryDir;
43
+ this.name = name;
44
+ this.type = null;
45
+ this.url = null;
46
+
47
+ this.XMLHttpRequest = function() {
48
+ var XHR = new self.hookInto;
49
+
50
+ return self.intercept(XHR, {
51
+ open: function(type, url) {
52
+ self.type = type.toUpperCase();
53
+ self.url = url;
54
+ },
55
+ send: function(data) {
56
+ var response = self.getCassetteFor(self.type, self.url);
57
+ var callback = this.onreadystatechange;
58
+ var fakeXHR = this;
59
+
60
+ if(!response) {
61
+ XHR.open(self.type, config.host + self.url);
62
+ XHR.send(data);
63
+ XHR.onreadystatechange = function() {
64
+ if(this.readyState === 4) {
65
+ self.setCassetteFor(self.type, self.url, this)
66
+ }
67
+ self.extend(fakeXHR, this);
68
+ }
69
+ } else {
70
+ self.extend(fakeXHR, response);
71
+ }
72
+ typeof callback == 'function' && callback();
73
+ }
74
+ });
75
+ };
76
+
77
+ this.extend = function(destination, source, object) {
78
+ for (var property in source) {
79
+ destination[property] = object ? (object[property] || source[property]) : source[property];
80
+ }
81
+ return destination;
82
+ };
83
+
84
+ this.intercept = function(source, object) {
85
+ return self.extend({}, source, object);
86
+ };
87
+
88
+ this.getCassetteFor = function(type, url) {
89
+ var cassette = VCRConstructor.Store.get(self.cassetteLibraryDir, self.name);
90
+ self.cassette = cassette ? cassette : {};
91
+ return self.cassette[type + "," + url];
92
+ };
93
+
94
+ this.setCassetteFor = function(type, url, response) {
95
+ self.cassette[type + "," + url] = response;
96
+ VCRConstructor.Store.set(self.cassetteLibraryDir, self.name, self.cassette);
97
+ }
98
+ };
99
+
100
+ VCRConstructor.prototype = {
101
+ constructor: VCRConstructor,
102
+
103
+ configure: function(fn) {
104
+ fn(this.config);
105
+ },
106
+
107
+ useCassette: function(name, fn) {
108
+ fn(new VCRConstructor.Context(name, this.config));
109
+ }
110
+ };
111
+
112
+ if(IS_NODE) {
113
+ module.exports = new VCRConstructor;
114
+ } else {
115
+ var VCR = new VCRConstructor;
116
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gerbil-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-23 00:00:00.000000000Z
12
+ date: 2012-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70103481229080 !ruby/object:Gem::Requirement
16
+ requirement: &70209328773680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70103481229080
24
+ version_requirements: *70209328773680
25
25
  description: Full support for the Rails 3.1 asset pipeline when testing your coffeescript
26
26
  or javascript files using Gerbil
27
27
  email: hi@nicolassanguinetti.info
@@ -45,6 +45,8 @@ files:
45
45
  - lib/gerbil/rails.rb
46
46
  - vendor/assets/javascripts/gerbil.js
47
47
  - vendor/assets/javascripts/jquery-1.7.1.js
48
+ - vendor/assets/javascripts/smoking.js
49
+ - vendor/assets/javascripts/vcr.js
48
50
  homepage: http://github.com/foca/gerbil-rails
49
51
  licenses: []
50
52
  post_install_message:
@@ -65,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
67
  version: '0'
66
68
  requirements: []
67
69
  rubyforge_project:
68
- rubygems_version: 1.8.10
70
+ rubygems_version: 1.8.11
69
71
  signing_key:
70
72
  specification_version: 3
71
73
  summary: Testing for Rails' Asset Pipeline using Gerbil