gerbil-rails 0.0.1 → 0.1.0

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.
@@ -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